Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL创建一对一关系_Mysql_Sql_Database_Database Design_Relational Database - Fatal编程技术网

MySQL创建一对一关系

MySQL创建一对一关系,mysql,sql,database,database-design,relational-database,Mysql,Sql,Database,Database Design,Relational Database,我正在创建一个数据库,这是我第一次使用它们 我有一个关于一对一通信的问题。我正在创建一个代表某项运动团队的表格 我希望每支球队只有一个比赛场地,每支球队都有自己的场地 竞技场将有许多属性(名称、座位、票价等),因此我会为它们创建一个表,即使我读到创建一对一关系的最佳实践是将所有内容放在一个表中 因为竞技场和团队是两个如此不同的概念,所以我会以如下方式将它们分为两个表: Club -------------------- ClubID (PK) ClubName . . . ArenaID (FK

我正在创建一个数据库,这是我第一次使用它们

我有一个关于一对一通信的问题。我正在创建一个代表某项运动团队的表格

我希望每支球队只有一个比赛场地,每支球队都有自己的场地

竞技场将有许多属性(名称、座位、票价等),因此我会为它们创建一个表,即使我读到创建一对一关系的最佳实践是将所有内容放在一个表中

因为竞技场和团队是两个如此不同的概念,所以我会以如下方式将它们分为两个表:

Club
--------------------
ClubID (PK)
ClubName
.
.
.
ArenaID (FK)


Arena
--------------------
ArenaID (PK)
ClubID (FK)
ArenaName
Seats
TicketPrice
此外,我认为竞技场不是自动递增的,而是与俱乐部出价相等,因为我会在创建俱乐部时自动创建竞技场。 这合理吗

我想很好地理解这种类型的关系,因为它也会用于其他情况(例如,每支球队都会有一名具有其技能的助理教练)

谢谢大家

编辑:

@凯文·鲍沃斯:我只是想说明一下比赛的情况,谢谢你的回答

@Peter Gluck您应该将竞技场视为俱乐部的一个属性,但它有其他自己的属性,我想将其与俱乐部表分开,以便更好地组织数据库。如果俱乐部想“建造”另一个竞技场,它只需更改实际竞技场的名称,就可以更改座位数和票价。但保存在数据库中的“对象”将保持不变。只会更改某些列

@布兰科·迪米特里耶维奇感谢你的详细回答。我想问你一些问题,以便更好地理解你所说的(我现在开始使用数据库)。 在第一个示例中,您没有为两个表使用两个键,一个是主键,另一个是外键,但是您只使用了一个键,同时也是主键和外键,是否正确?这两种选择有什么区别? 然后,你说如果我没有太多的团队,如果我把所有的都放在一张桌子上会更好,但我希望我会有几十(或者几百)个团队。在这种情况下,这个数字是否足以拆分表?我之所以这样说,是因为我在这个表中有不止一个一对一的关系,所以如果我把所有这些一对一的关系放在同一个表中,它会非常大

感谢大家的建议,现在我将尝试使用带有两个表和两个不同ID键的方法。
但我将在其他表中使用ypercube建议的方法

我喜欢把这些桌子分开的想法。它将使您的对象模型工作得更好

然而,关于:

此外,我还想把ArenaID不是自动递增的,而是 它等于俱乐部出价,因为我将自动创建竞技场 何时创建俱乐部。这合理吗


我会将ArenaID保留为它自己的自动整数。如果俱乐部更换竞技场会发生什么?这只是可能导致这些密钥不同步的一种情况。我有一种感觉,随着时间的推移,您将使用这种方法手动调整其中一些键。保持你的关系数据库,就是这样,保持关系数据库,不要依赖环境。

你似乎很理解这些概念。您确实正在考虑适当的考虑因素来推动您的决策。只要确保你所做的假设是正确的,并且将保持正确。。(也就是说,作为B队助理教练的个人是否永远不允许成为另一个队的助理教练?如果对于所有关系,这些问题的答案始终是肯定的,那么它们确实可以建模为一对一(事实上,您可以将它们都作为单个队表的属性,而不会丢失功能),但要小心,像这样的假设很少是真实的,而且随着应用程序和数据模型的发展,这些假设注定会随着时间的推移保持真实


假设这真的是一对一,那么我考虑把它们分解成单独的表的唯一原因是性能。属性集每秒要访问数百次,而大部分属性相当稳定,访问频率要低得多。然后,您可以将访问频率较高的属性放在更小、更窄的表中,以获得更好的读写性能。分离属性纯粹是为了逻辑或组织nal美学不是我会做的…

在支持可延迟约束的DBMS上,可以使用循环外键实现真正的“1对1”:

CREATE TABLE Club (
    ClubId INT PRIMARY KEY
    -- Other fields...
);

CREATE TABLE Arena (
    ClubId INT PRIMARY KEY REFERENCES Club (ClubId)
    -- Other fields...
);

ALTER TABLE Club ADD FOREIGN KEY (ClubId)
    REFERENCES Arena (ClubId)
    DEFERRABLE INITIALLY DEFERRED;
FK
Club->Arena
在交易结束前不会强制执行,因此您可以插入
Club
,然后插入
Arena
,而不会遇到鸡和蛋的问题


不幸的是,您将无法在MySQL中实现真正的“1对1”关系,因为它不支持延迟约束,因此您将无法在存在真正的“1对1”所必需的循环FK的情况下插入新数据时解决鸡和蛋的问题

您甚至无法真正依赖您提出的解决方案,因为MySQL不强制执行检查约束,因此您无法强制执行
ClubId
ArenaId
之间的相等性。可能您最好依靠应用程序逻辑来强制执行,从而使您面临潜在的错误

使用备用关键点(即唯一约束)也无济于事,因为:

CREATE TABLE Club (
    ClubId INT PRIMARY KEY,
    ArenaId INT UNIQUE
    -- Other fields...
);

CREATE TABLE Arena (
    ArenaId INT PRIMARY KEY,
    ClubId INT NOT NULL UNIQUE REFERENCES Club (ClubId)
    -- Other fields...
);

ALTER TABLE Club ADD FOREIGN KEY (ArenaId)
    REFERENCES Arena (ArenaId);

INSERT INTO Club (ClubId) VALUES (1);
INSERT INTO Club (ClubId) VALUES (2);
INSERT INTO Club (ClubId) VALUES (3);

INSERT INTO Arena (ArenaId, ClubId) VALUES (1, 2);
INSERT INTO Arena (ArenaId, ClubId) VALUES (2, 3);
INSERT INTO Arena (ArenaId, ClubId) VALUES (3, 1);

UPDATE Club SET ArenaId = 2 WHERE ClubId = 1;
UPDATE Club SET ArenaId = 3 WHERE ClubId = 2;
UPDATE Club SET ArenaId = 1 WHERE ClubId = 3;
现在你有一个俱乐部(
ClubId=1
)指向一个竞技场(
ArenaId=2
),它指向另一个俱乐部(
ClubId=3
)!等等

即使有效,聚集表中的二级索引也可能会很昂贵,而且很难使用


“垂直分割”理论
Club
--------------------
ClubID (PK)
ClubName
.
.

Arena
--------------------
ArenaID (PK)
ArenaName
Seats
.
.

ClubPlaysInArena
--------------------
ClubID  (PK, UQ1, FK1)
ArenaID (PK, UQ2, FK2)
.
.