1

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

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

否则,我的方法将是:

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

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

4

1 回答 1

1

在 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
于 2013-07-18T14:15:17.770 回答