mysql - MySQL 的高级唯一约束

标签 mysql unique-constraint

归结为我的问题的本质,我有一个带有 DATETIME 字段的 MySQL 表 (InnoDB),我需要实现重复检查,不允许多次使用相同的日期,精确到小时(例如,只有一行 2013-07-18 13:xx:xx)。

那么我的第一个问题是,是否有任何方法可以在 MySQL 数据库本身中强制执行此操作?

否则我的方法是:

  1. 为读写锁定表(避免
  2. 进行 SELECT 查询以验证我可以插入新行
  3. 插入
  4. 再次解锁 table

我真的不喜欢这个解决方案 - 任何关于如何在不锁定表的情况下执行此操作的建议都将不胜感激。

最佳答案

在 MySQL 中没有简单的、声明式的方法来做到这一点。但是您可以创建一个阴影列,并使用触发器来保持数据的一致性。这假设“ts”(下方)可以是任何有效的时间戳,但您每小时只需要其中一个。

create table test (
   ts datetime not null,
   ts_uniq char(13) not null,
   unique (ts_uniq)
);

列“ts_uniq”是阴影列。它将包含像“2013-01-01 08”这样的字符串。

create trigger bef_ins_test 
before insert on test
for each row
set new.ts_uniq = date_format(new.ts, '%Y-%m-%d %H');

您需要一个在更新前执行的类似触发器。

create trigger bef_upd_test 
before update on test
for each row
set new.ts_uniq = date_format(new.ts, '%Y-%m-%d %H');

当您为“ts”插入值时,阴影列会自动正确设置。

insert into test (ts) values ('2013-01-01 08:35:33');
select * from test;

ts                   ts_uniq
--
2013-01-01 08:35:33  2013-01-01 08

尝试插入略有不同的值会正确失败,并引发错误代码 1062(重复输入)。

insert into test (ts) values ('2013-01-01 08:47:13');

如果您更新现有时间戳,BEFORE UPDATE 触发器会保持列“ts_uniq”一致。

update test
set ts = '2013-01-01 17:42:42';

select * from test;

ts                   ts_uniq
--
2013-01-01 17:42:42  2013-01-01 17

尝试独立更新“ts_uniq”不会引发错误,但也不会更改行。

update test
set ts_uniq = '2013-12-31 18';

select * from test;

ts                   ts_uniq
--
2013-01-01 17:42:42  2013-01-01 17

关于mysql - MySQL 的高级唯一约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17722732/

相关文章:

flask - 从 flask_sqlalchemy 导入 UniqueConstraint

mysql日期查询,可以找到两个日期之间的日期,但不能找到date=

mysql - 性能套接字 nodejs + mysql

mysql - 这个 INSERT.. ON DUPLICATE 什么时候会失败?

mysql - 使用外列的唯一多列键

sql - 如何删除重复条目?

SSH 的 java.sql.Connection 扩展

mysql - 转义要在 Perl 中引用的字符串

mysql - JPA和MySQL : Knowing if start and end dates are aligned in a group by clause

postgresql - postgresql 分区的唯一索引