【问题标题】:Primary Key Index Automatic主键索引自动
【发布时间】:2012-06-28 23:54:38
【问题描述】:

我目前正在使用 mysql 做一个项目,并且是一个完美的初学者.....

我做了一个包含以下列的表格.....

            ID           // A integer type column which is a primary key........
            Date         // A Date type column.........
            Day          // A String column.........

现在我只想知道是否有任何方法可以自动生成ID 列插入值......??

例如: - 如果我插入 date - 4/10/1992Day - WED 作为值。 Mysql Server 应该会自动生成任何从1 开始的整数值,检查它们是否存在。 即在包含值的表中

             ID              Date              Day

             1              01/02/1987         Sun
             3              04/08/1990         Sun

如果我在上表中插入日期值和日期值(在示例中指定)。它应该插入为

             2              04/10/1992         WED

我尝试过使用自动增量器之类的方法.....但恐怕它只会增加 ID 值。

【问题讨论】:

  • 带有自动增量 ID 字段的主键将为您生成新的 ID。
  • 试试这个答案:stackoverflow.com/a/6280675/534877
  • @mazzucci...我在 ID 上设置了自动增量 ....它只是增加了 ID ......我想根据我展示的示例插入主键...... ...
  • 在示例中,您是否删除了第 2 行,现在要插入另一个?
  • 您与AUTO_INCREMENT 有差距,这没关系。无论如何,您不必将此ID 列公开给用户。如果有缝隙有什么问题?如果ID 定义为INT UNSIGNED,则您有 40 亿个号码。如果这还不够,请将其设为BIGINT UNSIGNED,然后您就有大约 16 个 quintillion 可用号码。

标签: mysql primary-key primary-key-design


【解决方案1】:

有一种方法可以做到这一点,但它会影响性能。继续并在列上保留 auto_increment,仅用于第一次插入,或者当您想要更快地插入时。

即使在列上使用 auto_increment,您也可以指定该值,只要它不与现有值冲突。

获取下一个值或第一个间隙:

SELECT a.ID + 1 AS NextID FROM tbl a
LEFT JOIN tbl b ON b.ID = a.ID + 1
WHERE b.ID IS NULL
ORDER BY a.ID
LIMIT 1

如果你得到一个空集,只需使用 1,或者让 auto_increment 做它的事情。

为了并发,您需要锁定表以防止其他会话使用您刚刚找到的下一个 ID。

【讨论】:

  • 对不起...说..但它很复杂....(也许因为是 mysql 的新手)....cud 你解释一下查询............ .??
【解决方案2】:

嗯...我理解您的问题...您希望以可以控制其限制的方式生成条目...

嗯,我有一个非常奇怪的解决方案……如果你愿意,可以接受它……

使用 unsigned int 在自动增量模式下使用您的主键创建您的表(正如这里建议的每个人)....

现在考虑两种情况......

如果您的餐桌需要每年或在一定期限内清零(如果存在这种情况)...... perform alter table 操作禁用自动增量模式并删除所有内容... 然后再次启用......

如果您正在做的是某种数据仓库......那么数据库可以使用多年...... 然后在插入之前包含一个 sql query to find the smallest primary key value using predefined key functions如果它超过 2^33 create a new table with the same details 你应该 maintain a seperate table to track the number of tables of this types

这个技巧有点复杂,恐怕....不存在您所期望的简单方法....

【讨论】:

  • hmm......有点好......这是否会使过程变慢,因为每次我们检查主键列中的最大最大值,即使它可能被索引...... ..
【解决方案3】:

您确实不需要覆盖从整数主键列中删除值所造成的空白。它们专门设计用于忽略这些差距。

自动增量机制可以设计为考虑顶部的间隙(在您删除一些具有最大 id 值的产品之后)或所有间隙。但这并不是因为它的设计目的不是为了节省空间,而是为了节省时间并确保不同的交易不会意外生成相同的 id。

事实上,PostgreSQL 实现了它的 SEQUENCE 数据类型/SERIAL 列(它们相当于 MySQL auto_increment),如果事务请求序列递增几次但最终不使用这些 id,它们永远不会习惯。这也是为了避免交易意外生成和使用相同 ID 的可能性。

您甚至无法节省空间,因为当您决定您的表将使用SMALLINT 这是一个固定长度的 2 字节整数时,这些值是全为 0 还是最大值都没有关系。如果您使用普通的INTEGER,那是一个固定长度的 4 字节整数。

如果您使用UNSIGNED BIGINT,这是一个 8 字节整数,这意味着它使用 8*8 位 = 64 位。使用 8 字节整数,您最多可以数 2^64,即使您的应用程序连续工作多年,它也不应该达到像 18446744070000000000 这样的 20 位数字(如果它确实在计算已知中的分子)宇宙?)。

但是,假设您确实担心 id 可能会在几年内用完,也许您应该使用 UUID 而不是整数。

维基百科指出,“只有在接下来的 100 年每秒生成 10 亿个 UUID 之后,仅创建一个副本的概率约为 50%”。

UUID 可以存储为 BINARY(16),如果您将它们转换为原始二进制文件,则可以存储为 CHAR(32)(如果您去掉短划线)或作为 CHAR(36)(如果您保留短划线)。

在 16 个字节中 = 128 位数据 UUID 使用 122 个随机位和 6 个验证位,它们是使用有关创建时间和地点的信息构建的。这意味着在不同的计算机上创建数十亿个 UUID 是安全的,并且发生冲突的可能性非常小(与在不同的计算机上生成自动递增的整数相反)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-07
    • 2011-07-01
    • 2013-08-30
    • 1970-01-01
    • 2018-12-01
    • 1970-01-01
    相关资源
    最近更新 更多