Mysql 唯一约束与插入前检查

Mysql 唯一约束与插入前检查,mysql,sql,sql-server,oracle,Mysql,Sql,Sql Server,Oracle,我有一个SQL server表RealEstate,其中包含列-Id、Property、Property\u值。这个表大约有500-1000万行,将来还会增加更多。仅当此表中不存在Id、Property、Property_值的组合时,我才希望插入一行 示例表- 1,Rooms,5 1,Bath,2 1,Address,New York 2,Rooms,2 2,Bath,1 2,Address,Miami 不允许插入2,地址,迈阿密。但是,2,价格,20亿是可以的。我很想知道做这件事的“最佳”方

我有一个SQL server表RealEstate,其中包含列-Id、Property、Property\u值。这个表大约有500-1000万行,将来还会增加更多。仅当此表中不存在Id、Property、Property_值的组合时,我才希望插入一行

示例表-

1,Rooms,5
1,Bath,2
1,Address,New York
2,Rooms,2
2,Bath,1
2,Address,Miami
不允许插入
2,地址,迈阿密
。但是,
2,价格,20亿
是可以的。我很想知道做这件事的“最佳”方法是什么,为什么。为什么部分对我来说最重要。检查的两种方法是:

  • 在应用程序级别-应用程序应在插入行之前检查行是否存在
  • 在数据库级别-在所有3列上设置唯一约束,并让数据库 进行检查,而不是个人/应用程序
  • 有没有一种情况会比另一种更好

    谢谢

    PS:我知道已经有一个类似的问题,但它不能回答我的问题-
    另外,我认为UNIQUE适用于所有数据库,因此我不认为应该删除mysql和oracle标记。

    对您的问题的描述正是为什么主键可以是复合的,例如,它们由多个字段组成。这样,数据库将为您处理唯一性,而您无需关心它

    在您的情况下,表定义可以类似于以下内容:

     CREATE TABLE `real_estate` (
       `id` int(11) NOT NULL AUTO_INCREMENT,
       `property` varchar(255) DEFAULT NULL,
       `property_value` varchar(255) DEFAULT NULL,
       PRIMARY KEY (`id`),
       UNIQUE KEY `index_id_property_property_value` (`id`, `property`, `property_value`),
     ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
    

    这并不能直接回答这个问题,但我认为把它贴在这里可能会有帮助,因为它比维基百科好,而且链接有一天可能会死掉

    链接-

    维基百科对种族状况有很好的描述,但如果你不了解编程的基础知识,就很难理解。我将尝试用不太专业的术语来解释它,使用如上所述的生成标识符的示例。我还将使用人类活动的类比来传达这些想法

    竞态条件是两个或多个程序(或单个程序的独立部分)都试图同时获取某些资源,从而导致错误答案或冲突。此资源可以是信息,如下一个可用的约会时间,也可以是对某些内容的独占访问,如电子表格。如果您曾经使用Microsoft Excel在共享驱动器上编辑文档,您可能有过Excel告知其他人已经在编辑电子表格的经历。此错误消息是Excel优雅地处理潜在竞争条件和防止错误的方法

    程序的一项常见任务是识别某种类型的下一个可用值,然后分配它。这项技术用于发票号码、学生ID等。这是一个以前解决过的老问题。最常见的解决方案之一是允许存储数据的数据库生成数字。还有其他解决方案,它们都有各自的优缺点

    不幸的是,那些不了解这一领域或仅仅不擅长编程的程序员经常试图自己动手。聪明的人会很快发现这是一个比看上去复杂得多的问题,并寻找现有的解决方案。坏的人永远看不到问题,或者,一旦他们看到了问题,就坚持在不纠正错误的情况下使他们不可行的解决方案变得更加复杂。让我们以学生ID为例。新手程序员说“要知道下一个学生编号应该是什么,我们只需获取最后一个学生编号并将其递增。”下面是在引擎盖下发生的事情:

  • 贝蒂,一个管理员。招生办公室的助理启动学生管理计划。请注意,这实际上只是在她的电脑上运行的程序的副本。它通过学校网络与数据库服务器通信,但无法与在其他电脑上运行的程序的其他副本通信
  • 贝蒂为鲍勃·史密斯创建了一个新的学生记录,输入了所有信息
  • 当贝蒂输入数据时,另一位管理员乔治。助理,在他的电脑上启动了学生管理程序,并开始为Gina Verde创造记录
  • 乔治打字更快,所以他和贝蒂同时完成。他们同时按下“保存”按钮
  • 贝蒂的程序连接到数据库服务器,获得使用中的最高学号5012
  • 同时,乔治的程序对同一个问题得到了相同的答案
  • 两个程序都决定要保存的记录的新学生ID应为5013。他们将这些信息添加到记录中,然后保存到数据库中
  • 现在鲍勃·史密斯(贝蒂的学生)和吉娜·维德(乔治的学生)有了相同的学生证
  • 学生证将附在所有其他记录上,从成绩到食堂的餐卡。最终,这个问题会暴露出来,有人将不得不花费大量时间为其中一人分配一个新ID,并整理出混淆的记录

    当我向人们描述这个问题时,通常的反应是“但在实践中这种情况会发生多久?永远不会,对吗?”。错。首先,当您的员工输入数据时,通常每个人都会在相对较短的时间内完成。这增加了重叠的可能性。如果所讨论的应用程序是对公众开放的web应用程序,那么两个人同时点击“保存”按钮的可能性更高。我最近在一个生产系统中看到了这一点。这是一个公开测试版的web应用程序。使用率很低,每天只有少数人注册。然而,六对人在几个月的时间里成功地获得了相同的身份证。如果你想知道,没有,我和我的团队中的任何人都没有写那段代码。然而,我们很惊讶地发现