`
乡村里的一条土狗
  • 浏览: 70298 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

数据库约束:使用它们还是放弃它们?

阅读更多

 

作者简介:
Frank Sommers is president of Autospaces. He also is a Senior Editor with Artima Developer.

 

概述

关系型数据库提供了丰富的特性来保证数据的完整性。然而,除了常用的设计规范,很少有企业应用利用这些功能特性,相反,他们倾向于在应用层里实现对数据完整性的检查。如果sql数据约束有价值的话,为什么那么多应用不使用它呢?

 

关于数据管理,有一个很重要的趋势,特别是在Web应用上,人们乐于使用弱SQL模式 或者是完全避免忽略关系数据的一些基本原则。在Artima最近一个讨论是关于“NoSQL”运动的,跟以前一样 通常的讨论结果基本认为数据库关系约束很有用处,开发者需要自己去承担不使用约束带来的后果。

 

这显而易见,规范的关系数据模型存在之初就是为了保证数据的完整性的。用户通常会认为数据库是一个有保障的数据来源:它为我们常用的数据查询提供了一个基本的概念,就像SQL查询,它返回的数据就是一种“正确无误”的数据。但如果你把关系约束给禁掉了,把大部分的数据完整性维护放在应用层的代码里,那对这种“正确无误”的保证是很困难的。

很多的关于NoSQL的讨论都是围绕着反数据库标准的问题 弱化SQL规范会导致脏数据的产生 现代数据管理制度,比如这个SQL标准,提供了很多额外的机制去确保数据的完整性。在细读了最新版的 Joe Celko's  SQL for Smarties 被高度推荐的一本书 它让我明白应该用最少的SQL功能来保证数据的完整性。例如,我建表时从来不用SQL检查机制,我也不使用其它的标准SQL工具,为的就是让数据库更加干净。

 

尽管我很相信尽量使用数据管理系统的诸多好处,我还是倾向于在domain和controller层的代码里实现数据完整性相关的操作。当然,所有的代码都需要认真的测试。最近我统计了为数不少的我用   ScalaTest  写成的测试套件,大概有上百个测试用例,我发现有不低于30%的测试用例会要求在应用层强制检查数据完整约束。举个例子,测试用例会检查 API-level 的前提条件 比如,检查null值是否被正确的处理。如果一个复杂的对象被当作一个方法的参数,我会写代码测试这个方法能否在这个复杂对象参数状态异常时正常处理。

 

我一直这样做,即使是在实体层使用了 Hibernate Validator 、认真的声明了  entity classes  里需要校验的约束条件。最后,我们好要认真的在表现层 对于我,这里是Flex 写大量的数据完整性检查代码去确保用户提交有效的数据到server端API里。表现层的代码也有测试用例。总之,由于此,我们在实体层、表现层、数据层编码来确保数据完整性,同时在测试用例里相当的一部分都用在覆盖对控制层、表现层的完整性检查。

 

这样会有大量的代码直接违反DRY原则。我所知道的对非冗余数据完整性校验最有好感的程序是在 ActiveRecord , Rails' O/R mapping and persistence layer. ActiveRecord 在实体层类里声明完整性约束。 Rail 的控制层和表现层使用这些数据资料可以在数据有问题时向用户显示友好的错误信息。然而,跟 Hibernate Validator 相比, ActiveRecord 很少使用数据库丰富的底层提供的功能:这两个框架生成的约束性的sql语句几乎对外键和 non-null 域的声明有所保留,而其他的约束检查是在某种校验层实现的(部分约束在实体类里)。

 

我想,在一个较为理想的方案里,数据库应该对数据有保护作用,包括强制约束。这种效果我们也可以通过写大量的SQL来实现,但这不会是个很合适的方法,因为大多数的SQL数据库都依赖于SQL错误码来指示约束异常。例如,设置一个约束,salsry 字段不能接受小于5000或者大于100000的数据,当用户试图插入一个100的薪水值时数据库会返回一个错误码 但这个错误码很难被转换成应用中其它层中可以使用的信息。我们不去这样做是因为这样做的价值很小,特别是这种转换在不同的数据库之间还不能兼容。

 

你认为什么地方是最合适的定义数据约束的地方呢?你是否同意SQL应该提供更多的标准错误码来提示数据违法约束条件呢?

 

外刊IT评论  

28
4
分享到:
评论
13 楼 zhouzhao21 2009-10-26  
ivy1107 写道
简单的说,就是,
function function1{
……
function2(a,b);
……
}

function function2(a, b){
……
}

是在function1中验证参数a,b是否合法。还是在function2中验证a,b是否合法。


两个都验证或至少要验证面向外部的函数。
12 楼 ivy1107 2009-10-05  
简单的说,就是,
function function1{
……
function2(a,b);
……
}

function function2(a, b){
……
}

是在function1中验证参数a,b是否合法。还是在function2中验证a,b是否合法。
11 楼 whaosoft 2009-09-30  
我感觉还是别放弃吧
10 楼 fandayrockworld 2009-09-29  
有公认的缺陷,以后必定会有牛的公司或组织出相应的解决方案!用Java Web举例子,如: 开始我们用jsp+servlet,感觉层次不分明,于是有了strus;我们感觉每次用jdbc方式操作数据库太繁琐,于是有了hibernate;我们感觉程序模式不科学,于是有了spring(可能spring初衷不是这个,请大家斧正)。
如果你是一个大牛,那么就赶紧把你认为程序流程中有缺陷的步骤仔细的想一下,自己研究,或许你就是下一个流行框架的盘古。
9 楼 kkppccdd 2009-09-29  
如果数据源只被一个应用使用,约束做在哪里都一样。但如果数据源会被多个应手使用(或以后应用层更新或干脆更换了个应用层),数据库的约束就很关键了。
8 楼 dotaking 2009-09-29  
我反对

je补丁
7 楼 giginet 2009-09-28  
从来就不用外键,也很少用。有的时候直接去后台删除一条数据,用外键真的好麻烦,尤其是关联很多的情况下。
6 楼 yantoba 2009-09-27  
虽然我未曾参加过火星圈的讨论
不过我也是一直保留主键,去除外键
5 楼 RockyWoo 2009-09-27  
bupolongyi 写道
我在做的建设银行的项目.. 就完全放弃的外键约束
很不懂这么做的必要性... 因为我觉得如果没有约束 数据完整性就缺失了
不过这系统甚至已经跑了4年了.. 从项目初期到现在新加的子项目 所有的表结构
都没有使用外键关联,在一对一 或者一对多的表中.. 只是添加了一方的某个唯一字段 而不是ID.. 比如说部门表下有 ID属性 和部门编号 都是唯一的.. 然后在多方用部门编号表示一对多的关系..但没有使用外键.. 这么搞到底有什么好处?

我大概知道你做哪个项目了O(∩_∩)O哈哈~
4 楼 soleghost 2009-09-27  
在业务变化频繁、海量数据库的系统中,数据库底层不适合外键
对于数据的完整性、一致性,可以通过应用层保证
3 楼 bupolongyi 2009-09-27  
我在做的建设银行的项目.. 就完全放弃的外键约束
很不懂这么做的必要性... 因为我觉得如果没有约束 数据完整性就缺失了
不过这系统甚至已经跑了4年了.. 从项目初期到现在新加的子项目 所有的表结构
都没有使用外键关联,在一对一 或者一对多的表中.. 只是添加了一方的某个唯一字段 而不是ID.. 比如说部门表下有 ID属性 和部门编号 都是唯一的.. 然后在多方用部门编号表示一对多的关系..但没有使用外键.. 这么搞到底有什么好处?
2 楼 徐风子 2009-09-27  
看题目是个很“强力”的话题呀。
1 楼 opensdp 2009-09-26  
原文的这个帖子讨论的很厉害

相关推荐

    数据库习题及答案

    三级模式分别是内模式、模式和外模式,它们之间的关系是:内模式描述了数据库的物理存储结构,模式描述了数据库的逻辑结构,外模式描述了数据库的用户视图。 3. 数据模型的三个要素:数据模型的三个要素分别是数据...

    关系型数据库与nosql数据库.doc

    此外,关系型数据库的实体完整性、参照完整性和用户定义的完整性提供了良好的数据约束,减少了数据冗余和不一致性。 然而,随着互联网的快速发展,尤其是Web 2.0时代的到来,传统的关系型数据库开始面临新的挑战。...

    Delphi Edit方法编辑数据库中的内容

    4. 如果数据库表有外键约束,编辑时要考虑这些约束,避免违反规则。 总结,Delphi中的Edit方法是编辑数据库记录的关键步骤,配合TDBEdit控件和其他数据组件,能实现直观的用户界面和高效的数据管理。正确理解和使用...

    mysql数据库优化方案

    为提高查询效率,确保使用索引的列不含NULL值,可设定默认值或使用NOT NULL约束。 2. **避免全表扫描**:尽量避免使用!=或操作符,以及在WHERE子句中使用OR,这些都可能导致全表扫描。如果必须使用,可以尝试改写...

    大数据技术原理与应用之NoSQL数据库.pptx

    3. **数据库模式**:RDBMS有固定的数据库模式和约束,NoSQL则允许动态定义和存储不同类型的结构化数据。 4. **查询效率**:RDBMS通过索引机制实现快速查询,适合简单和结构化查询;NoSQL缺乏传统索引,但可通过...

    第一章测验_ 分布式数据库原理与应用.

    4. **NoSQL数据库**:问题4和14介绍了NoSQL数据库,如Redis、MongoDB和HBase,它们通常用于处理大规模、非结构化数据,具备可扩展性和灵活的数据模式。Oracle虽然也是一个数据库,但它属于关系型数据库。 5. **适合...

    2014年广州大学《数据库原理》期末考试试卷(含答案).pdf

    - 当关系R和S进行自然连接运算时,如果想要保留原该舍弃的元组,可以使用**外连接(Outer Join)**。**左外连接(Left Outer Join)**会保留左边表的所有行,即使右边表没有匹配的行也会显示,而**右外连接(Right Outer ...

    大数据技术原理与应用-实验4NoSQL和关系数据库的操作比较(林子雨)

    通过对NoSQL数据库与关系数据库的深入对比,我们可以看出它们各自的优势和局限性。在实际应用中,选择哪种类型的数据库取决于具体的需求和应用场景。随着大数据技术的不断发展,NoSQL数据库将在越来越多的领域发挥...

    数据库技术复习题1 选择题答案.doc

    数据库技术复习题1选择题答案涵盖了数据库系统的多个关键知识点,包括数据模型、数据库管理系统(DBMS)、数据库设计、关系操作、事务处理、数据完整性、并发控制以及分布式数据库等多个方面。 1. 外模式:外模式是...

    数据库系统原理.docx

    3. 数据库管理系统(DBMS)是建立、配置和使用数据库的软件,负责管理数据的存储、检索和更新。 4. SQL中,涉及空值(NULL)的操作,如`AGE IS NULL`和`AGE IS NOT NULL`是正确的,而`AGE=NULL`和`NOT(AGE IS NULL)`...

    数据库原理试题库8.doc

    【数据库原理】试卷主要考察了数据库系统的基本概念、数据模型、数据操作、数据库设计与管理等方面的知识。以下是对试卷中涉及知识点的详细说明: 1. **数据库系统的特点**:题目中提到的数据库系统特点,正确答案...

    北邮数据库期末考试-单选题

    它定义了数据库的结构、数据类型、完整性约束等信息。 ### 自然连接 19. **左外连接**:在关系R与关系S进行自然连接时,如果只保留R中原该舍弃的元组,同时保留S中的匹配元组,这样的操作称为左外连接。左外连接会...

    数据库优化设计之三十六计

    使用`IN`或`OR`操作可能会导致优化器放弃使用索引。尽量使用`BETWEEN`或适当的范围查询来替代。 **第二十七计:利用hint提示强制使用索引** 在SQL语句中使用hint(提示)来指导优化器使用特定的索引。这对于那些...

    对象关系数据库

    然而,重要的是要记住当初为何放弃这些机制——它们带来了复杂性和维护难题。尽管如此,将对象定位引入到关系数据库领域时,“老朋友”重新出现,这提示我们不应盲目复现历史错误。 #### 四、从COBOL到SQL:效率与...

    一种面向海量分布式数据库的嵌套查询策略.pdf

    NoSQL数据库放弃了关系型数据库严格的事物一致性模型和范式约束,转而采用弱一致性模型,以支持分布式和水平扩展,大大增强了对海量数据的管理和处理能力。 接着,我们要明白NoSQL数据库与关系数据库的主要区别。...

    信息系统数据库关键技术专业课程设计要求.doc

    【信息系统数据库关键技术专业课程设计要求】 信息系统数据库设计是IT领域中的关键环节,它涉及到数据的组织、存储和访问,对于高效、稳定的信息系统的构建至关重要。本课程设计旨在让学生深入理解和掌握数据库技术...

    mysql面试题20道

    MySQL 面试题总结 ...可以通过以下步骤来处理 MySQL 数据库 cpu 飙升情况:使用 top 命令观察,确定是 MySQLd 导致还是其他原因。如果是 MySQLd 导致的,show processlist,查看 session 情况,确定问题所在。

Global site tag (gtag.js) - Google Analytics