一个相当复杂的自动增量

时间:2014-01-07 18:59:14

标签: mysql

这是一个比一对多连接更复杂的想法。我有一堆表,如照片,帖子,用户等,可以评论。我的评论表包含3个有助于识别评论的字段:

item-id - 评论所属项目的ID table - item-id所在的表格(保存为整数,但在下面显示为名称以避免混淆)
id - 评论的ID,相对于item-id

更好理解的示例:

id  item-id table

1   1       photos
2   1       photos
1   1       posts
2   1       posts
1   2       posts
1   1       users

现在问题在于插入。我发现很难确定当前的最后一个id。根据上面的表格,如果用户要对item-id = 1的照片发表评论,则新评论需要具有3的ID。我能想到的唯一方法是在插入时运行子查询但我不是子查询的忠实粉丝。是否有一些内置在mysql中的机制可以帮助我实现这一目标,或者任何其他简单而强大的方法?

3 个答案:

答案 0 :(得分:2)

你应该考虑一件事,为什么这对你很重要? ID的目的是成为唯一标识符。当然,它可以代表顺序,因为它是单调增加的,但是有没有理由它为每个(item-id, table)对特别需要从1到2变为3?如果它是1,6,20,那会有害吗?

如果你正在使用PHP,你仍会以相同的顺序接收数据,而在PHP中,很容易知道哪个是1,2和3。

答案 1 :(得分:2)

来自你的评论:

  

我想到这一点是因为害怕独特的ID用完了。我知道mysql可以存储的最大整数值是1 * 10到19或者其他东西,这是一个非常大的数字,但不是无限的。除了巨大的数字占用更多的空间?

MySQL的签名INT类型最多可以达到2 31 -1。无符号INT可以达到2 32 -1,即4,294,967,295。

你是对的,这不是无限的,但42亿非常高,能够轻松应对大多数需求。

您还可以使用有符号或无符号BIGINT,它是8字节,是INT大小的两倍,但如果您需要大于INT的值,则必须存储它们。

无符号BIGINT上升到2 64 -1或18,446,744,073,709,551,615。即使你每小时多次重新加载整个数据库,你真的,真的,真的,不太可能在你的生命中耗尽这些价值。


重新评论。

是的,大多数数据类型都是固定大小的,这意味着它们在每一行上使用相同数量的字节,而不管您在任何给定行中存储的值。这样做的原因是您可以稍后更改该值,并且如果MySQL必须找到更多空间来将小数值增长为大数值,则会导致其他类型的性能问题。

有关MySQL对每种数据类型使用的字节数的详细信息,请参阅http://dev.mysql.com/doc/refman/5.6/en/storage-requirements.html

例外是一些字符串数据类型(VARCHAR,VARBINARY,TEXT,BLOB),每行使用可变数量的空间,具体取决于您实际使用的字符串的长度。

但MySQL中没有 numeric date / time 数据类型,大小不一。

另一个评论:你应该问问自己多少时间&你正在努力优化这一点,以及获得更大的磁盘是否更经济。如果您拥有一个大型数据库,那么每个整数每行额外的4个字节会增加,但是在真正重要之前您需要存储数十亿行。

答案 2 :(得分:1)

MyISAM allows you to do this easily

  

对于MyISAM和BDB表,您可以在a上指定AUTO_INCREMENT   多列索引中的辅助列。

但是,它仅限于两列,因此您仍需要将其标准化以删除其中一列。

否则,您可以插入下一个用户(第1项)行,如下所示:

INSERT INTO table1 (id, `item-id`, `table`)
SELECT MAX(id) + 1, 1, 'users' FROM table1 WHERE `item-id` = 1 AND `table` = 'users'

为了扩展它,IFNULL部分允许您使用相同的子句插入第一行。

INSERT INTO table1 (id, `item-id`, `table`)
SELECT IFNULL(MAX(id), 0) + 1, 2, 'users' FROM table1 WHERE `item-id` = 2 AND `table` = 'users'

在这种情况下,您可能会有一个多列主键,包含所有三列。