There's no simple, declarative way to do this in MySQL. But you can create a shadowing column, and use triggers to keep the data consistent. This assumes that "ts" (below) can be any valid timestamp, but that you want only one of them per hour.
create table test (
ts datetime not null,
ts_uniq char(13) not null,
unique (ts_uniq)
);
The column "ts_uniq" is the shadowing column. It will hold strings like '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');
You'll need a similar trigger that executes before updates.
create trigger bef_upd_test
before update on test
for each row
set new.ts_uniq = date_format(new.ts, '%Y-%m-%d %H');
When you insert values for "ts", the shadowing column is automatically set correctly.
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
Trying to insert a slightly different value fails correctly, raising error code 1062 (duplicate entry).
insert into test (ts) values ('2013-01-01 08:47:13');
If you update the existing timestamp, the BEFORE UPDATE trigger keeps the column "ts_uniq" consistent.
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
Trying to independently update "ts_uniq" won't raise an error, but it won't change the row, either.
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