如何在数据库中实施数据完整性规则?
我正在设计这个类和抽象(MustInherit)类的集合
类图http://img396.imageshack.us/img396/1711/nodeclassinheritanceej0.gif
这是我要存储所有这些的数据库表
数据库表http://img179.imageshack.us/img179/3237/nodetablenorootln3.gif
据Microsoft SQL Server数据库所知,这些都是可空("允许空")列。
但实际上,这取决于存储在其中的类:LinkNode,HtmlPageNode或者CodePageNode。
规则可能看起来像这样...
规则表http://img127.imageshack.us/img127/74/datarulesha0.gif
如何在数据库中强制执行此类数据完整性规则?
更新:关于这种单表设计...
我仍在尝试将最终体系结构归零。
我最初是从许多几乎零个nullalbe字段的小表开始的。
哪种导航最适合我的数据库架构?
我了解了LINQ to SQL IsDiscriminator属性。
在SQL中处理一对一关系的最佳方法是什么?
但是后来我了解到LINQ to SQL仅支持单表继承。
LINQ to SQL IsDiscriminator列不能继承吗?
现在,我尝试使用类和抽象类的集合来处理它。
请帮助我处理我的.NET抽象类。
解决方案
回答
对于每种类型的节点,都有一个唯一的表。
为什么不让正在构建的类为其自己的类型强制实现数据完整性?
编辑
在这种情况下,我们可以a)使用逻辑约束(请参见下文)或者b)存储过程进行插入/编辑(无论如何都是个好主意),或者c)再次使类强制数据完整性。
我将把C和B混合在一起。我将具有用于每个节点类型(即Insert_Update_NodeType)的添加/编辑的唯一存储过程,以及使该类在保存数据之前执行数据验证。
回答
这可能不是我们想听到的答案,但是避免逻辑不一致的最好方法是,我们确实希望查看数据库规范化
回答
SQL Server对类一无所知。我认为我们必须通过使用Factory类来强制执行此操作,该类为我们构造/解构所有这些构造,并确保根据类型传递正确的值。
从技术上讲,这不是"强制数据库中的规则",但我认为这不能在单个表中完成。字段或者接受空值,或者不接受。
另一个想法可能是探索执行相同功能的SQL函数和存储过程。但是,我们不能对一个记录强制将字段设置为NOT NULL,而对下一个记录将其设置为NULL。那是业务层/工厂工作。
回答
我对SQL Server不太熟悉,但是我知道对于Oracle,我们可以指定约束,这些约束可用于执行我们要查找的操作。我很确定我们也可以在SQL Server中定义约束。
编辑:我发现此链接似乎有很多信息,有点长,但可能值得一读。
回答
斯蒂芬的答案是最好的。但是,如果必须,我们可以在HtmlOrCode列和其他需要更改的列中添加检查约束。
回答
在表上使用CHECK约束。这些允许我们使用任何类型的布尔逻辑(包括表中的其他值)来允许/拒绝数据。
从联机丛书网站:
You can create a CHECK constraint with any logical (Boolean) expression that returns TRUE or FALSE based on the logical operators. For the previous example, the logical expression is: salary >= 15000 AND salary <= 100000.
回答
看起来我们正在尝试"单表继承"模式,这是《企业应用程序体系结构的模式》一书的"对象关系结构模式"部分所涵盖的模式。
如果我们希望通过SQL表约束来强制数据完整性,则建议使用"类表继承"或者"具体表继承"模式。
尽管这不是我的第一个建议,但是我们仍然可以使用"单表继承",并通过存储过程强制执行约束。
回答
我们可以设置一些插入/更新触发器。只需检查这些字段是否为null或者notnull,并在需要时拒绝插入/更新操作即可。如果要将所有数据存储在同一表中,这是一个很好的解决方案。
我们还可以为每个类创建一个唯一的表。
回答
我们是否尝试过NHibernate?它比Entity Framework成熟得多。免费。
回答
我个人始终坚持通过触发器或者检查约束将数据完整性代码放在表本身上。原因是我们不能保证仅用户界面会更新插入或者删除记录。我们也不能保证某人可能不会写第二个sp来绕过原始sp的约束而又不了解实际的数据完整性规则,甚至不会写它,因为他或者她不知道该sp存在规则。表通常受DTS或者SSIS包,来自用户界面或者通过查询分析器或者查询窗口的动态查询,甚至受运行代码的计划作业的影响。如果我们不将数据完整性代码放在表级别,则迟早数据将不具有完整性。