Mysql SQL一对一关系(第二个表中的其他实体属性)的优点
有好几次我看到模型具有1到(1或0)关系。例如:Mysql SQL一对一关系(第二个表中的其他实体属性)的优点,mysql,sql,sql-server,database,Mysql,Sql,Sql Server,Database,有好几次我看到模型具有1到(1或0)关系。例如: CREATE TABLE accounts(login VARCHAR PRIMARY KEY, password VARCHAR); CREATE TABLE people(login VARCHAR PRIMARY KEY, name VARCHAR, inn VARCHAR, age INTEGER...); 有时people在登录列上也设置了外键,有时则没有 所以我的问题是这样一个模型的优点和缺点是什么?这里的表格是否正常化了?(据我所
CREATE TABLE accounts(login VARCHAR PRIMARY KEY, password VARCHAR);
CREATE TABLE people(login VARCHAR PRIMARY KEY, name VARCHAR, inn VARCHAR, age INTEGER...);
有时people
在登录列上也设置了外键,有时则没有
所以我的问题是这样一个模型的优点和缺点是什么?这里的表格是否正常化了?(据我所知,他们是,但他们看起来还是很奇怪)
另外,我有一个关于数据库的家庭作业,我需要设计一个足够复杂的模型。这是一些学生为了制作更多表而使用的一种技术。建立一对一关系的一个实际原因是为了解决MySQL存储引擎的行大小限制,而不为某些列实现LOB类型存储(将它们移动到行外存储) 对于最大行大小,InnoDB的实际限制仅为8000多字节。只要几个VARCHAR(4000)列就可以让您超过这个限制 另一个原因是它们实际上是独立的实体。这里,我使用的术语“实体”是实体关系建模技术中常用的术语,(粗略地)定义为“我们需要存储信息的可以唯一识别的人、地点、事物、概念或事件”。如果表是两个真正独立的实体,我们通常希望将它们实现为独立的表。关系的“1对1”性质不是我们在两个实体之间发现的通常关系(需求发现方面)。我们更经常发现实体之间存在一对多或多对多的关系 实现1对1(或1对0或1)的另一个原因是,每个表的内容都由不同的流程“管理”。例如,一个负责在“person”表中添加/更新行的进程,可能有一个隔夜作业从外部源加载该表。还有另一个过程负责添加/更新
accounts
表,可能是一个在线web表单应用程序。我们有时会发现,最好是每个表都由一个流程“管理”
这是我的三大理由。否则,我只会对一个实体使用一个表。使用一对一关系的一个实际原因是为了解决MySQL存储引擎的行大小限制,而不为某些列实现LOB类型的存储(将它们移动到行外存储) 对于最大行大小,InnoDB的实际限制仅为8000多字节。只要几个VARCHAR(4000)列就可以让您超过这个限制 另一个原因是它们实际上是独立的实体。这里,我使用的术语“实体”是实体关系建模技术中常用的术语,(粗略地)定义为“我们需要存储信息的可以唯一识别的人、地点、事物、概念或事件”。如果表是两个真正独立的实体,我们通常希望将它们实现为独立的表。关系的“1对1”性质不是我们在两个实体之间发现的通常关系(需求发现方面)。我们更经常发现实体之间存在一对多或多对多的关系 实现1对1(或1对0或1)的另一个原因是,每个表的内容都由不同的流程“管理”。例如,一个负责在“person”表中添加/更新行的进程,可能有一个隔夜作业从外部源加载该表。还有另一个过程负责添加/更新
accounts
表,可能是一个在线web表单应用程序。我们有时会发现,最好是每个表都由一个流程“管理”
这是我的三大理由。否则,对于一个实体,我只使用一个表。除了斯宾塞的原因之外,还有一些原因: 安全性:在表上指定安全性比在列上指定安全性更容易。通过将密码放在一个单独的表中——即使是加密的——访问它们更容易控制 性能:这称为“垂直分区”。通常,一组列可能占据记录中5%的空间,但满足90%的查询。读取附加列的开销可能很大 神秘的要求:如果需要清除所有密码,可以通过
truncate table
而不是update来完成代码>。除了性能之外,一个很大的优势是单个密码不会出现在日志中
触发器:如果某些列具有update
触发器,可能需要将它们隔离在单独的表中,以减少触发器调用的频率
至于这是否违反了正常化原则。可能会,也可能不会。这取决于单独的实例是否“看起来”像单独的实体
此外,我不会将登录名
作为公共密钥。我会将这些表定义为:
CREATE TABLE accounts (
AccountId int not null auto_increment primary key,
login VARCHAR unique
password VARCHAR
);
CREATE TABLE people (
PersonId int not null auto_increment primary key,
AccountId int references account(AccountId)
name VARCHAR,
. . .
);
(这是示意图。MySQL忽略内联引用声明,因此您需要一个显式的外键约束。)除了Spencer的原因之外,还有一些原因:
安全性:在表上指定安全性比在列上指定安全性更容易。通过将密码放在一个单独的表中——即使是加密的——访问它们更容易控制
性能:这称为“垂直分区”。通常,一组列可能占据记录中5%的空间,但满足90%的查询。读取附加列的开销可能很大
神秘的要求:如果需要清除所有密码,可以通过truncate table
而不是update来完成代码>。除了性能之外,还有一个很大的优势,就是单个密码不会出现在日志中