sve*_*ltr 7 database database-design relational-database
假设我的数据库中有以下表:
表http://www.freeimagehosting.net/uploads/a5ef036857.png
现在我的所有查询都依赖于Company表.为了简化我的SQL查询,为每个其他表提供(冗余)关系是否是一种不好的做法?
编辑1:背景是框架的使用问题.请参阅Django:限制模型数据.
编辑2:没有元组会改变他的公司.
编辑3:我不写mysql查询.我使用抽象层(django).
这是不好的做法,因为您的冗余数据必须独立更新,因此必须冗余.一个充满潜在错误的过程.(甚至必须单独分配和维护自动级联)
通过引入此关系,您可以有效地反规范化数据库.为了提高性能,有时需要非规范化,但从你的问题来看,这听起来只是简化你的SQL.
使用其他机制来抽象数据库的复杂性:视图,存储过程,UDF
为每个其他表提供与 Company 表的(冗余)关系以简化我的 sql 查询是一种不好的做法吗?
是的,绝对的,因为当您将客户关系更新到公司或部门到公司时,这意味着更新每个冗余关系——如果您错过任何此类更新,您现在拥有一个充满冗余数据的数据库。这是一个糟糕的非规范化。
如果您的目的只是简化您的 SQL,请考虑使用视图来“带来”父数据。这是通过客户加入将 company_id 拉入合同的视图:
create view contract_customer as
select
a.*,
b.contract_id, b.company_id
from
contract a
join customer b on (a.customer_id = b.customer_id);
Run Code Online (Sandbox Code Playgroud)
这个连接很简单,但为什么要一遍又一遍地重复呢?写一次,然后在其他查询中使用该视图。
许多(但不是全部)RDBMS 甚至可以优化联接,如果您没有将来自 customer 的任何列放入选择列表或基于视图的查询的 where 子句中,只要您使 contract.customer_id 具有外键customer.customer_id 上的参照完整性约束。(在没有这样的约束的情况下,不能省略连接,因为这样就有可能存在客户中不存在的 contract.customer_id。因为你永远不会想要那个,你将添加外键约束。)
使用视图可以实现您想要的效果,无需更新子表的时间开销,也无需通过添加冗余列来使子行变宽的空间开销(当您有很多行时,这真的很重要,因为越宽行,一次可以放入内存的行越少),最重要的是,当父项更新但子项不更新时,不会出现数据不一致的可能性。
你问的是你的设计中是否违反了第三范式.如果没有充分的理由,这样做是不可行的,因为通过创建冗余,您可能会在数据中出现错误和不一致的可能性.此外,使用冗余数据"简化"模型以支持某些操作可能会使其他操作复杂化.此外,可能需要不必要地复制约束和其他数据访问逻辑.
| 归档时间: |
|
| 查看次数: |
2878 次 |
| 最近记录: |