Postgresql 复合唯一键(LastName、FirstName、MiddleName)不起作用?
Posted
技术标签:
【中文标题】Postgresql 复合唯一键(LastName、FirstName、MiddleName)不起作用?【英文标题】:Postgresql composite unique keys (LastName, FirstName, MiddleName) not working? 【发布时间】:2014-01-27 10:31:53 【问题描述】:我在 Laravel (postgresql) 中有以下架构
Schema::create('members', function(Blueprint $table)
$table->increments('id');
$table->string('lname');
$table->string('fname');
$table->string('mname')->nullable();
$table->string('ename', 10)->nullable();
$table->unique(array('lname', 'fname', 'mname'));
);
如您所见,我有一个由lname
、fname
和mname
组成的复合唯一键。但是我将mname
设置为nullable()
,因为并非所有人都有中间名。
但是,当向数据库添加数据时(postgresql)
DB::table('students')->insert(
array(
array(
'lname' => 'Last 1',
'fname' => 'First 1'
),
array(
'lname' => 'Last 1',
'fname' => 'First 1'
)
)
);
保存成功!我做错了吗?解决方法是什么?请帮忙。
【问题讨论】:
请显示您的 ORM / 任何抽象工具生成的实际表和约束,并且 实际 SQL 作为插入命令的结果运行。要获取表定义,请连接psql
并运行 \dt members
。对于 SQL,请从您的 ORM 查询日志中找出它。
请阅读kalzumeus.com/2010/06/17/… 并重新考虑此架构。
@CraigRinger 非常好的文章,但我相信他需要更好地理解 NULLS 的概念。使用名称作为键会在某些时候严重烧伤你。但是,不要否认一个人有奋斗和经历的特权吗?
当您尝试插入另一个叫 John Smith 的人时会发生什么?
【参考方案1】:
记住基本规则:
NULL!= NULL or NULL <> NULL
即使两者都有一个NULL
值,它们也无法进行比较,因为它们是未定义的。 NULL
不等于没有。 NULL
等于未定义。像这样想NULL
就像查克诺里斯,因为没有什么可以与查克诺里斯相提并论。
所以你的钥匙:
Last1 NULL First1
Last1 NULL First1
独一无二,因为 NULLS
无法比较。
要使其正常工作,将 NULL
中间名默认为 ''
字符串或零长度字符串。
【讨论】:
小问题:正确的术语应该是 unknown 而不是 undefined。对于三值逻辑:真、假、未知。 @Denis yes unknown 是正确的,但是 Chuck Norris 比较并不能很好地工作。以上是关于Postgresql 复合唯一键(LastName、FirstName、MiddleName)不起作用?的主要内容,如果未能解决你的问题,请参考以下文章