Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 一个相当复杂的自动增量_Mysql - Fatal编程技术网

Mysql 一个相当复杂的自动增量

Mysql 一个相当复杂的自动增量,mysql,Mysql,这是一个比一对多连接更复杂的想法。我有一大堆表格,比如照片、帖子、用户等等,可以对它们进行评论。“我的评论”表包含3个字段,可帮助识别评论: 项目id-注释所属项目的id 表格-项目id所在的表格(保存为整数,但在下面显示为名称以避免混淆) id-注释的id,相对于项目id 更好理解的示例: id item-id table 1 1 photos 2 1 photos 1 1 posts 2 1 posts 1 2

这是一个比一对多连接更复杂的想法。我有一大堆表格,比如照片、帖子、用户等等,可以对它们进行评论。“我的评论”表包含3个字段,可帮助识别评论:

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

更好理解的示例:

id  item-id table

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

现在的问题是插入。我发现很难确定当前的最后一个id。根据上表,如果用户要对
项目id
=1的照片发表评论,则新评论的id必须为3。我能想到的唯一方法是在insert上运行子查询,但我不太喜欢子查询。MySQL中是否有一些机制可以帮助我实现这一目标,或者其他任何容易和稳健的方式?

< P> >你应该考虑一下,为什么这对你很重要?ID的用途是作为唯一标识符。当然,它可以表示顺序,因为它是单调递增的,但是有没有任何理由特别需要为每个
(项目id,表格)
对从1到2到3?如果它是1,6,20,会有那么大的危害吗


如果你使用PHP,你仍然会收到相同的数据,在PHP中,很容易知道哪一个是1, 2和3。

你应该考虑一件事,为什么这对你很重要?ID的用途是作为唯一标识符。当然,它可以表示顺序,因为它是单调递增的,但是有没有任何理由特别需要为每个

(项目id,表格)
对从1到2到3?如果它是1,6,20,会有那么大的危害吗

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

:

对于MyISAM和BDB表,可以在 多列索引中的第二列

但是,它被限制为两列,因此您仍然需要对此进行规范化以删除其中一列

否则,您可以按如下方式插入下一个用户(项目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'
在这种情况下,您可能有一个多列主键,由所有三列组成。

:

对于MyISAM和BDB表,可以在 多列索引中的第二列

但是,它被限制为两列,因此您仍然需要对此进行规范化以删除其中一列

否则,您可以按如下方式插入下一个用户(项目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'
在这种情况下,您可能有一个多列主键,由所有三列组成。

您的评论:


我之所以想到这一点,是因为担心独特的ID会用完。我知道mysql可以存储的最大整数值是1*10到第19位,这是一个非常大的数字,但不是无限大的。以及庞大的数字占用更多的空间

MySQL的签名INT类型可以达到231-1。无符号整数可以达到232-1,即4294967295

你是对的,这不是无限的,但42亿是相当高的,很容易满足大多数需求

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

未签名的BIGINT上升到264-1或18446744073709551615。即使您每小时多次重新加载整个数据库,您也不太可能在一生中耗尽这些值


这是你的评论

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

有关MySQL为每种数据类型使用的字节数的更多信息,请参阅

例外情况是某些字符串数据类型(VARCHAR、VARBINARY、TEXT、BLOB)根据实际使用的字符串长度,每行使用可变的空间量

但是MySQL中没有大小不同的数字或日期/时间数据类型

另一条评论:您应该问问自己,您在优化这个方面花费了多少时间和精力,以及仅仅获得一个更大的磁盘是否更经济。如果您有一个大型数据库,那么每行每整数额外增加4个字节是正确的,但在它真正起作用之前,您需要存储数十亿行。

您的评论:


我之所以想到这一点,是因为担心独特的ID会用完。我知道mysql可以存储的最大整数值是1*10到第19位,这是一个非常大的数字,但不是无限大的。以及庞大的数字占用更多的空间

MySQL的签名INT类型可以达到231-1。无符号整数可以达到232-1,即4294967295

你是对的,这不是无限的,但42亿是相当高的,很容易满足大多数需求

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

未签名的BIGINT上升到264-1或18446744073709551615。即使您每小时多次重新加载整个数据库,您也不太可能在一生中耗尽这些值


这是你的评论

是的,大多数