Pav*_*ykh 74 database database-design relational-database
对不起那个noob问题,但有没有真正需要与数据库中的表一对一的关系?您可以在一个表中实现所有必需的字段.即使数据变得非常大,您也可以在SELECT语句中枚举所需的列名而不是使用SELECT *.你什么时候真的需要这种分离?
Bra*_*vic 91
超级和子类之间的"1到0..1"用作实现继承的 "单独表中的所有类"策略的一部分.
"1到0..1"可以在单个表中表示,其中"0..1"部分由NULL-able字段覆盖.但是,如果关系大多为 "1到0"且只有几个"1到1"行,则将"0..1"部分拆分为单独的表可能会节省一些存储(和缓存性能)的好处.有些数据库在存储NULL方面比其他数据库更节省,因此这种策略变得可行的"截止点"可能有很大差异.
真正的"1对1"垂直分区数据,这可能会影响缓存.数据库通常在页面级别实现缓存,而不是在单个字段级别实现缓存,因此即使您只选择一行中的几个字段,通常也会缓存该行所属的整个页面.如果一行非常宽并且所选字段相对较窄,那么您最终将缓存大量您实际不需要的信息.在这种情况下,垂直分区数据可能很有用,因此只有较窄,更频繁使用的部分或行被缓存,因此更多的部分可以适应缓存,使缓存有效"更大".
垂直分区的另一个用途是更改锁定行为:数据库通常无法锁定单个字段的级别,仅锁定整个行.通过拆分行,您只允许锁定其中一个半部分.
触发器通常也是特定于表的.虽然理论上你只能有一个表并且触发器忽略了行的"错误的一半",但是某些数据库可能会对触发器可以做什么和不能做什么施加额外的限制,这可能会使这不切实际.例如,Oracle不允许您修改变异表 - 通过使用单独的表,只有其中一个表可能会发生变异,因此您仍然可以从触发器中修改另一个表.
单独的表可以允许更细粒度的安全性.
在大多数情况下,这些注意事项无关紧要,因此在大多数情况下,您应该考虑将"1对1"表合并到一个表中.
sup*_*erM 15
如果将两个一对一表放在一个表中,可能会出现语义问题.例如,如果每个设备都有一个遥控器,那么将设备和遥控器的一堆特性放在一个表中并不是很好.您甚至可能需要花时间确定某个属性是属于设备还是遥控器.
可能存在这样的情况,即一半的列将长时间保持空置,或者永远不会被填充.例如,汽车可能有一个具有一堆特征的拖车,或者可能没有.所以你将拥有许多未使用的属性.
如果您的表有20个属性,并且偶尔只使用其中的4个,那么将表分成2个表以解决性能问题是有意义的.
在这种情况下,将所有内容都放在一个表中并不好.此外,处理具有45列的表格并不容易!
san*_*zti 13
我的2美分.
我在一个大型应用程序中开发的地方工作,一切都是模块.例如,我们有一个users表,我们有一个模块可以为用户添加facebook详细信息,另一个模块可以向用户添加twitter详细信息.我们可以决定拔掉其中一个模块并从我们的应用程序中删除其所有功能.在这种情况下,每个模块都将自己的表与1:1关系添加到全局users表中,如下所示:
create table users ( id int primary key, ...);
create table users_fbdata ( id int primary key, ..., constraint users foreighn key ...)
create table users_twdata ( id int primary key, ..., constraint users foreighn key ...)
Run Code Online (Sandbox Code Playgroud)
Fen*_*ton 11
使用它的最明智的时间是,如果有两个单独的概念,只会以这种方式相关.例如,汽车只能有一个当前的驱动程序,而驱动程序一次只能驱动一辆汽车 - 因此汽车和驾驶员的概念之间的关系将是1比1.我接受这是一个人为的例子来证明点.
另一个原因是你想以不同的方式专门化一个概念.如果您有一个Person表并想要添加不同类型的Person的概念,例如Employee,Customer,Shareholder - 这些中的每一个都需要不同的数据集.它们之间类似的数据将在Person表上,专家信息将在Customer,Shareholder,Employee的特定表上.
有些数据库引擎很难有效地将新列添加到一个非常大的表(很多行),我看到扩展表用于包含新列,而不是新列添加到原始表中.这是其他表的更可疑用途之一.
您可能还决定将两个不同表之间的单个概念的数据划分为性能或可读性问题,但如果您从头开始,这是一个相当特殊的情况 - 这些问题将在稍后展示.
首先,我认为这是一个建模和定义独立实体组成的问题。假设您有customers一个且只有一个address. 当然,你可以在一个表中实现所有内容customer,但是如果将来你允许他有 2 个或更多地址,那么你将需要重构它(不是问题,但要做出有意识的决定)。
我还可以想到其他答案中未提及的一个有趣的案例,其中拆分表格可能很有用:
再次想象一下,您每个人都有customers一个address,但这次可以选择是否有地址。当然,您可以将其实现为一堆NULL-able 列,例如ZIP,state,street. 但假设你确实有一个,那么addressthestate不是可选的,但 theZIP是。如何在单个表中对其进行建模?您可以在表上使用约束customer,但划分到另一个表并使foreign_key 可以为空要容易得多。这样,您的模型就可以更明确地表明该实体 address是可选的,并且这ZIP是该实体的可选属性。
您指的是数据库规范化。我可以在我维护的应用程序中想到的一个示例是 Items。该应用程序允许用户销售多种不同类型的商品(即库存商品、非库存商品、服务商品等...)。虽然我可以将每个项目所需的所有字段存储在一个 Items 表中,但拥有一个包含所有项目通用的字段的基本项目表,然后为每个项目类型(即库存、非库存、等..),其中包含特定于该项目类型的字段。然后,项目表将具有它所代表的特定项目类型的外键。特定项目表和基本项目表之间的关系将是一对一的。
下面,是一篇关于规范化的文章。
http://support.microsoft.com/kb/283878
不经常.
如果你需要实现一些安全性,你可能会发现一些好处 - 所以有些用户可以看到一些列(table1)而不是其他用户(table2).
当然,一些数据库(Oracle)允许您在同一个表中执行此类安全性,但有些数据库可能不会.
我在实践中通常会遇到两种常见的 1:1 关系:
IS-A relationships, also known as supertype/subtype relationships. This is when one kind of entity is actually a type of another entity (EntityA IS A EntityB). Examples:
In all these situations, the supertype entity (e.g. Person, Item or Car) would have the attributes common to all subtypes, and the subtype entities would have attributes unique to each subtype. The primary key of the subtype would be the same as that of the supertype.
"Boss" relationships. This is when a person is the unique boss or manager or supervisor of an organizational unit (department, company, etc.). When there is only one boss allowed for an organizational unit, then there is a 1:1 relationship between the person entity that represents the boss and the organizational unit entity.
| 归档时间: |
|
| 查看次数: |
27326 次 |
| 最近记录: |