我对数据库设计比较陌生,我决定制作自己的假设数据库以进行实践。但是,我无法对其进行建模和规范化,因为我认为存在许多多对多 (M:N) 关系。
该数据库旨在保留有关在塞尔达系列中工作过的各种人物的数据。我想跟踪的控制台(S) ,一个游戏可以玩上,员工是曾在部分游戏的发展,乔布斯的员工有(很多员工在不同的工作职位在多个游戏等)
我必须为涉及音乐艺术家描述的业务环境设计实体关系图 (ERD) ,我将在下面详细说明。
一个艺术家有一个名称,且必须要么一组 或一个独奏演员(但不能同时)。
一个小组由一名或多名独舞者组成,并有若干成员(应根据组成该组的独奏者人数计算)。
一个独奏演员可能是一个会员众多的群体或无的集团,并可以播放一个或多个仪器。
如何构建一个 ERD 来表示这种场景?我对它的“或”部分感到困惑。
我有一个带有如下表的 PostgreSQL 9.5.3 DB:
container
id: uuid (pk)
... other data
thing
id: uuid (pk)
... other data
container_thing
container_id: uuid (fk)
thing_id: uuid (fk)
primary key (container_id, thing_id)
Run Code Online (Sandbox Code Playgroud)
Acontainer
可以指向任意数量的thing
s(没有重复),并且 athing
可以被任意数量的container
s指向。
可能有大量的容器和东西(取决于我们有多少客户)。每个容器中可能只有 1 到 10 个东西。我们一次最多只能查询大约 20 个容器。一个容器可以是空的,我需要取回一个空数组。
我需要构建代表容器的 json 对象,如下所示:
{
"id": "d7e1bc6b-b659-432d-b346-29f3a530bfa9",
... other data
"thingIds": [
"4e3ad81b-f2b5-4220-8e0e-e9d53c80a214",
"f26f49e5-76b4-4363-9ffe-9654ba0b0f0d"
]
}
Run Code Online (Sandbox Code Playgroud)
这工作正常,但我通过使用两个查询来做到这一点:
select * from "container" where "id" in (<list of container ids>)
select * from "container_thing" where "container_id" in …
Run Code Online (Sandbox Code Playgroud) 我有两个表:
这些公司允许其员工为其他公司工作。所以一个员工可以在很多公司工作,一个公司可以有很多员工(多对多关系)。
假设我有 3 名员工和他们工作的公司,分别具有一天的开始和结束时间。
employee_name | company_name | hours they work |
Akash A 09:00 - 11:00
B 12:00 - 02:00
C 04:00 - 07:00
Sunny D 09:00 - 11:00
C 12:00- 04:00
D 05:00 - 07:00
Vishal B 09:00 - 12:00
A 12:00 - 05:00
Run Code Online (Sandbox Code Playgroud)
我有一个containers
可以与多个表建立多对多关系的表,假设它们是plants
,animals
和bacteria
。每个容器可以包含任意数量的植物、动物或细菌,并且每个植物、动物或细菌可以在任意数量的容器中。
到目前为止,这非常简单,但我遇到的问题是每个容器应该只包含相同类型的元素。例如,同时包含植物和动物的混合容器应该是数据库中的约束违规。
我的原始架构如下:
containers
----------
id
...
...
containers_plants
-----------------
container_id
plant_id
containers_animals
------------------
container_id
animal_id
containers_bacteria
-------------------
container_id
bacterium_id
Run Code Online (Sandbox Code Playgroud)
但是对于这个模式,我无法想出如何实现容器应该是同构的约束。
有没有办法通过参照完整性来实现这一点,并在数据库级别确保容器是同类的?
我为此使用 Postgres 9.6。
我有 3 个“大”表,它们连接在一对列上(都是int
s)。
每个表在Key1
、上都有一个聚集索引Key2
,然后还有一个列。Key1
具有低基数并且非常偏斜。它总是在WHERE
子句中被引用。条款中Key2
从未提及WHERE
。每个连接都是多对多的。
问题在于基数估计。每个连接的输出估计变小而不是变大。当实际结果达到数百万时,这导致最终估计值低至数百。
我有什么办法可以让 CE 做出更好的估计吗?
SELECT 1
FROM Table1 t1
JOIN Table2 t2
ON t1.Key1 = t2.Key1
AND t1.Key2 = t2.Key2
JOIN Table3 t3
ON t1.Key1 = t3.Key1
AND t1.Key2 = t3.Key2
WHERE t1.Key1 = 1;
Run Code Online (Sandbox Code Playgroud)
我尝试过的解决方案:
Key1
,Key2
join sql-server many-to-many sql-server-2016 cardinality-estimates
再会,
我们大学的 db 教授总是说,在一侧与 (0, M) 的一对多关系必须有第三个表来关联它们。我当时没有问他,现在我也不能,但我想知道他为什么要这样说?(特别是必须的部分)。
我正在建模一个简单的传感器测量活动数据库,我对此感到非常困惑,您如何看待我的模型,它会按我的预期工作吗?这与我的问题有关,因为我正在做与我所教的完全不同的事情,而且我害怕构建一个损坏的模型。
传感器有 0 或 M 个度量,一个度量恰好属于一个传感器。活动有 0 或 M 个传感器,一个传感器可能在 0 或 N 个活动中。活动有 0 或 M 个度量,一个度量完全属于一个活动。
使用我教授的方法,我得到 6 个表(每对中间表)。我认为不需要其中的 2 个表,但理解这就是这个问题的目的。
忽略他,我得到了 Measure 和另一个表(多对多中的第三个表,我称之为 Instrument)都关联的 Campaign 和 Sensor。我认为拥有这样一种双重关系看起来是错误的,注意到 Measure 和 Instrument 都会有 FK 到 Campaign 和 Sensor(Instrument 就像一个空的度量,IMO),我决定简单地做我所做的。
我可能需要查询任何组合(给定活动的传感器/测量值和给定传感器的测量值),我想我可以轻松(?)做到这一点(在涉及测量时使用子查询)。我还希望,如果我删除一个活动或一个传感器,它的度量会被删除,我可以通过删除级联轻松实现这一点。会有什么缺点?
对不起,新手问题,任何帮助将不胜感激。我已经用谷歌搜索并没有发现任何东西,也许我使用了错误的术语,我不是在这里假装垃圾邮件。至少对 Google 搜索进行更智能的查询将不胜感激,谢谢。
我有一个 SellerProduct 表。表格中的每一行代表卖家提供的产品信息。SellerProduct 表包含以下列:
id (serial, pk)
productName (nvarchar(50))
productDescription (ntext)
productPrice (decimal(10,2))
sellerId (int, fk to Seller table)
Run Code Online (Sandbox Code Playgroud)
不同卖家的产品可能相同,但每个卖家的 productName、productDescription 和 productPrice 可能不同。
例如,考虑产品 TI-89。卖家 A 可能拥有产品的以下信息:
productName = TI-89 Graphing Calc
productDescription = A graphing calculator that...
productPrice 65.12
Run Code Online (Sandbox Code Playgroud)
卖家 B 可能拥有以下产品信息:
productName = Texas Instrument's 89 Calculator
productDescription = Feature graphing capabilities...
productPrice 66.50
Run Code Online (Sandbox Code Playgroud)
管理员用户需要确定不同卖家的产品是相同的。
我需要一种方法来捕获这些信息(即卖家的产品是相同的)。我可以创建另一个名为 SellerProductMapper 的表,如下所示:
sellerProductId1 (int, pk, fk to SellerProdcut table)
sellerProductId2 (int, pk, fk to SellerProdcut table)
Run Code Online (Sandbox Code Playgroud)
这种方法的问题在于它允许对给定行的 SellerProductId1 和 SellerProductId2 来自同一个卖家。这不应该被允许。 …
想象一下三个表的设置,User、Group 和 UserGroup,其中 UserGroup 由指向每个 User 和 Group 表的简单外键组成。
User
----
id
name
Group
-----
id
name
UserGroup
---------
user_id
group_id
Run Code Online (Sandbox Code Playgroud)
现在,我想编写一个查询,选择所有指定组中的所有用户。例如,从用户是“group1”、“group2”和“group3”中的每一个的一部分的用户中选择*。
使用 Django ORM 查询,我会做类似的事情
users = (
User.objects
.filter(user_group__group_id=group1.id)
.filter(user_group__group_id=group2.id)
.filter(user_group__group_id=group2.id)
)
Run Code Online (Sandbox Code Playgroud)
这将为每次调用产生一个连接.filter
,例如
SELECT * FROM users
INNER JOIN user_group g1 ON g1.user_id = id
INNER JOIN user_group g2 ON g2.user_id = id
INNER JOIN user_group g3 ON g3.user_id = id
WHERE g1.group_id = %s
AND g2.group_id = %s
AND g3.group_id = %s
Run Code Online (Sandbox Code Playgroud)
如果我要查询一个更大的集合来匹配,这会变得有点麻烦。
那么有什么更好的方法来做到这一点呢?如果我要问“任何”而不是“所有”,如果是一个简单的问题
SELECT …
Run Code Online (Sandbox Code Playgroud) 使用此处的其他问题和 Postgresql 文档,我设法构建了一个多对多自联接表。
但是添加一个WHERE
条款给我带来了麻烦。
问题:
ACategory
可以有许多子类别和许多父类别。给定 a category.Id
,我想检索类别、类别儿童、儿童的儿童等。
示例:给定这个结构:
child_1
child_11
child_111
child_112
child_1121
child_21
child_2
Run Code Online (Sandbox Code Playgroud)
给定:一个子句 id = child_11
预期结果:
child_11, child_111, child_112, child_1121
,
实际结果: child_11, child_111, child_112
这是我的尝试:http : //sqlfiddle.com/#!17/3640f/2
如果 Sqlfiddle 关闭:https ://www.db-fiddle.com/#&togetherjs=LhDjxfPHo6
注意:我不在乎复制 where 子句,我的应用程序可以处理
表结构:
CREATE TABLE Category(id SERIAL PRIMARY KEY, name VARCHAR(255));
CREATE TABLE Categories(parent_id INTEGER, child_id INTEGER, PRIMARY KEY(parent_id, child_id));
ALTER TABLE Categories ADD FOREIGN KEY (parent_id) REFERENCES category (id);
ALTER TABLE Categories ADD …
Run Code Online (Sandbox Code Playgroud) many-to-many ×10
postgresql ×4
join ×2
array ×1
constraint ×1
erd ×1
json ×1
mysql ×1
recursive ×1
self-join ×1
sql-server ×1
subtypes ×1
table ×1