Lim*_*eni 54 mysql sql database database-design one-to-one
现在我知道有一对一关系的答案,但他们都没有回答我的问题,所以请在下来之前阅读这个:)
我试图在MySQL数据库中实现一对一的关系.例如,假设我有"用户"表和"帐户表".我想确定用户只能拥有一个帐户.并且每个用户只能有一个帐户.
我找到了两个解决方案,但不知道该使用什么,还有其他选择.
DROP DATABASE IF EXISTS test;
CREATE DATABASE test CHARSET = utf8 COLLATE = utf8_general_ci;
USE test;
CREATE TABLE users(
id INT NOT NULL AUTO_INCREMENT,
user_name VARCHAR(45) NOT NULL,
PRIMARY KEY(id)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;
CREATE TABLE accounts(
id INT NOT NULL AUTO_INCREMENT,
account_name VARCHAR(45) NOT NULL,
user_id INT UNIQUE,
PRIMARY KEY(id),
FOREIGN KEY(user_id) REFERENCES users(id)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;
Run Code Online (Sandbox Code Playgroud)
在此示例中,我在指向用户主键的帐户中定义外键.然后我将外键设为UNIQUE,因此帐户中不能有两个相同的用户.要连接表,我会使用此查询:
SELECT * FROM users JOIN accounts ON users.id = accounts.user_id;
Run Code Online (Sandbox Code Playgroud)
DROP DATABASE IF EXISTS test;
CREATE DATABASE test CHARSET = utf8 COLLATE = utf8_general_ci;
USE test;
CREATE TABLE users(
id INT NOT NULL AUTO_INCREMENT,
user_name VARCHAR(45) NOT NULL,
PRIMARY KEY(id)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;
CREATE TABLE accounts(
id INT NOT NULL AUTO_INCREMENT,
account_name VARCHAR(45) NOT NULL,
PRIMARY KEY(id),
FOREIGN KEY(id) REFERENCES users(id)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;
Run Code Online (Sandbox Code Playgroud)
在此示例中,我创建了从主键指向另一个表中的主键的外键.由于主键默认为UNIQUE,因此这种关系一对一.要连接表,我可以使用:
SELECT * FROM users JOIN accounts ON users.id = accounts.id;
Run Code Online (Sandbox Code Playgroud)
现在的问题是:
我正在使用MySQL Workbench,当我在EER图中设计One To One关系时,让MySQL Workbench生成SQL代码,我得到一对多的关系:S这让我很困惑:S
如果我将这些解决方案中的任何一个导入到MySQL Workbench EER图中,它会将关系视为一对多:这也是令人困惑的.
那么,在MySQL DDL中定义一对一关系的最佳方法是什么.有什么选择可以实现这一目标?
谢谢!!
Bra*_*vic 42
由于主键默认为UNIQUE,因此这种关系一对一.
不,这使关系"一到零或一".那是你真正需要的吗?
如果是,那么你的"第二个解决方案"会更好:
顺便说一下,你需要制作accounts.id一个普通的整数(不是自动增量)来实现这一点.
如果不是,请参阅下文......
在MySQL中创建一对一关系的最佳方法是什么?
好吧,"最好"是一个重载的词,但"标准"解决方案将与任何其他数据库相同:将两个实体(用户和帐户在您的情况下)放在同一物理表中.
除了这两个之外还有其他解决方案吗?
从理论上讲,你可以在两个PK之间制作循环FK,但这需要延迟约束来解决鸡与蛋问题,遗憾的是MySQL不支持这个问题.
如果我将这些解决方案中的任何一个导入到MySQL Workbench EER图中,它会将关系视为一对多:这也是令人困惑的.
我对这个特定的建模工具没有太多的实际经验,但我猜这是因为它是"一对多",其中"很多"方面通过使其独特而被限制在1.请记住,"很多"并不意味着"1或许多",它意味着"0或许多",因此"上限"版本的确意味着"0或1".
1不仅在附加字段的存储费用中,而且在二级索引中也是如此.由于您使用的InnoDB 始终聚集表,因此请注意,在集群表中,二级索引比在基于堆的表中更昂贵.
您的第一种方法是在帐户表中创建两个候选键:id和user_id.
因此,我建议采用第二种方法,即使用外键作为主键.这个: