我有一个属于不同用户的项目表:
project_id,owner_user_id,project_name
我不需要project_names对表是全局唯一的,因此使project_name UNIQUE没有帮助。我想阻止用户在INSERT或UPDATE上创建重复的project_names。
在INSERT / UPDATE时,我只想检查是否已经存在属于特定owner_user_id的project_name,如果它已经存在,则INSERT / UPDATE应该失败。
我可以使用SELECT首先在用户的项目中检查project_name是否存在,然后如果select没有返回结果,则只执行INSERT / UPDATE。但这是多线程的,另一个线程可以在执行SELECT之后但在INSERT / UPDATE之前立即插入相同的project_name。将这一切都纳入交易感觉就像是矫枉过正。是否有单个查询可以执行此操作?
答案 0 :(得分:1)
您可以在两列中添加UNIQUE constraint作为一对:
alter table your_table add unique (owner_user_id, project_name)
这将确保project_name
值对每个用户而言是唯一的。您需要查看collation set up以确保比较project_name
值,而不考虑大小写。或者,您可以在访问数据库之前将项目名称标准化为标题大小写。
除非必须,否则不要尝试手工维护数据完整性,让数据库尽可能地处理您的约束。
答案 1 :(得分:0)
这确实需要在交易中。您需要检索一些信息(“哪些名称已被使用?”)然后对其进行操作(“如果我的名字未被使用,则使用它”)。这必须以原子方式完成。
正如你所推测的那样,如果在检查后插入没有原子地发生,就会出现竞争条件。
这是交易的目的。
答案 2 :(得分:0)
您可以在两个字段上添加唯一约束
CONSTRAINT C_UNICITY UNIQUE (owner_user_id, project_name)
每次尝试插入或更新存在重复的记录时,都会出现sql错误
答案 3 :(得分:0)
$result = mysql_query("select * from Project where owner_user_id='1';");
if (mysql_affected_rows()==0) {
$result = mysql_query("insert into Project (projectname) values ('pojectname');");
答案 4 :(得分:0)
根据数据库参照完整性违规,为您提供陷阱错误通常不是UI验证的首选形式 - 您通常需要更高抽象级别的东西。但是,对于使用事务和UNIQUE约束来保护您的数据和用户一样,没有什么特别“过分”。