mysql两列主键,带自动递增

Sys*_*ral 27 mysql

我有多个具有相同结构的数据库,有时会复制数据.为了保持数据完整性,我使用两列作为主键.一个是数据库ID,它链接到一个表,其中包含有关每个数据库的信息.另一个是表键.它不是唯一的,因为它可能有多个行,这个值相同,但在database_id列中有不同的值.

我打算将这两列放入一个联合主键.但是,我还想将表键设置为自动增量 - 但是基于database_id列.

EG,有了这些数据:

table_id   database_id     other_columns
1          1
2          1
3          1
1          2
2          2
Run Code Online (Sandbox Code Playgroud)

如果我要添加包含dabase_id为1的数据,那么我希望table_id自动设置为4.如果dabase_id输入为2,那么我希望table_id自动设置为3等.

在MySql中实现此目的的最佳方法是什么.

DTi*_*ing 42

如果你使用myisam

http://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html

对于MyISAM和BDB表,您可以在多列索引中的辅助列上指定AUTO_INCREMENT.在这种情况下,AUTO_INCREMENT列的生成值计算为MAX(auto_increment_column)+ 1 WHERE prefix = given-prefix.当您想要将数据放入有序组时,这非常有用.

CREATE TABLE animals (
    grp ENUM('fish','mammal','bird') NOT NULL,
    id MEDIUMINT NOT NULL AUTO_INCREMENT,
    name CHAR(30) NOT NULL,
    PRIMARY KEY (grp,id)
) ENGINE=MyISAM;

INSERT INTO animals (grp,name) VALUES
    ('mammal','dog'),('mammal','cat'),
    ('bird','penguin'),('fish','lax'),('mammal','whale'),
    ('bird','ostrich');

SELECT * FROM animals ORDER BY grp,id;

Which returns:

+--------+----+---------+
| grp    | id | name    |
+--------+----+---------+
| fish   |  1 | lax     |
| mammal |  1 | dog     |
| mammal |  2 | cat     |
| mammal |  3 | whale   |
| bird   |  1 | penguin |
| bird   |  2 | ostrich |
+--------+----+---------+
Run Code Online (Sandbox Code Playgroud)

对于你的例子:

mysql> CREATE TABLE mytable (
    ->     table_id MEDIUMINT NOT NULL AUTO_INCREMENT,
    ->     database_id MEDIUMINT NOT NULL,
    ->     other_column CHAR(30) NOT NULL,
    ->     PRIMARY KEY (database_id,table_id)
    -> ) ENGINE=MyISAM;
Query OK, 0 rows affected (0.03 sec)

mysql> INSERT INTO mytable (database_id, other_column) VALUES
    ->     (1,'Foo'),(1,'Bar'),(2,'Baz'),(1,'Bam'),(2,'Zam'),(3,'Zoo');
Query OK, 6 rows affected (0.00 sec)
Records: 6  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM mytable ORDER BY database_id,table_id;
+----------+-------------+--------------+
| table_id | database_id | other_column |
+----------+-------------+--------------+
|        1 |           1 | Foo          |
|        2 |           1 | Bar          |
|        3 |           1 | Bam          |
|        1 |           2 | Baz          |
|        2 |           2 | Zam          |
|        1 |           3 | Zoo          |
+----------+-------------+--------------+
6 rows in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

  • @ Demonslay335这似乎不是真的 - 这在带有InnoDB的MySQL 5.5中不起作用.因此,没有事务的辅助AUTO_INCREMENT ...... (4认同)
  • @ Demonslay335它在InnoDB中不起作用,除非你将主键的顺序改为(id,grp)而不是(grp,id),显然自动增量列必须先行. (4认同)
  • **警告!**这会导致复制问题,请参阅http://dev.mysql.com/doc/refman/5.1/en/replication-features-auto-increment.html`对包含复合主数据库的表的INSERT包含不是此复合键的第一列的AUTO_INCREMENT列的键不安全[..]` (3认同)
  • @Brilliand Odd,我在文档中看到了它.我确实遇到了它在我的生产服务器上运行的问题(MySQL 5.5.34).我最终让我的应用程序通过使用数据库在内部完成的相同查询来完成工作(`MAX(auto_increment_column)+ 1 WHERE prefix = given-prefix`). (2认同)
  • 据我所知,该功能永远不会被放入InnoDB.我在8.0中没有看到它.建议你在bugs.mysql.com上投票. (2认同)

Jon*_*ack 21

这是使用innodb的一种方法,由于聚集的复合索引,它也非常高效 - 只有innodb才能使用...

http://dev.mysql.com/doc/refman/5.0/en/innodb-index-types.html

drop table if exists db;
create table db
(
db_id smallint unsigned not null auto_increment primary key,
next_table_id int unsigned not null default 0
)engine=innodb;

drop table if exists tables;
create table tables
(
db_id smallint unsigned not null,
table_id int unsigned not null default 0,
primary key (db_id, table_id) -- composite clustered index
)engine=innodb;

delimiter #

create trigger tables_before_ins_trig before insert on tables
for each row
begin
declare v_id int unsigned default 0;

  select next_table_id + 1 into v_id from db where db_id = new.db_id;
  set new.table_id = v_id;
  update db set next_table_id = v_id where db_id = new.db_id;
end#

delimiter ;


insert into db (next_table_id) values (null),(null),(null);

insert into tables (db_id) values (1),(1),(2),(1),(3),(2);

select * from db;
select * from tables;
Run Code Online (Sandbox Code Playgroud)