与 MySQL AUTO INCREMENT 等效的 PostgreSQL 数据类型是什么?
我正在从 MySQL 切换到 PostgreSQL,我想知道如何才能拥有带有 AUTO INCRMENT
的 INT
列。 我在 PostgreSQL 文档中看到一种名为 SERIAL
的数据类型,但在使用它时出现语法错误。
I'm switching from MySQL to PostgreSQL and I was wondering how can I have an INT
column with AUTO INCREMENT
. I saw in the PostgreSQL docs a datatype called SERIAL
, but I get syntax errors when using it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
是的,SERIAL 是等效函数。
SERIAL 只是围绕序列创建表时间宏。 您无法更改现有列上的 SERIAL。
Yes, SERIAL is the equivalent function.
SERIAL is just a create table time macro around sequences. You can not alter SERIAL onto an existing column.
您可以使用任何其他整数数据类型,例如
小整数。
示例:
最好使用您自己的数据类型,而不是用户串行数据类型。
You can use any other integer data type, such as
smallint
.Example :
Better to use your own data type, rather than user serial data type.
如果你想将序列添加到表中已经存在的 id 中,你可以使用:
If you want to add sequence to id in the table which already exist you can use:
从 Postgres 10 开始,还支持 SQL 标准定义的标识列:
创建一个除非明确要求否则无法覆盖的标识列。 以下插入将因定义为
始终生成
的列而失败:但是,这可以被否决:
当使用
默认生成
选项时,这与现有生成的行为本质上相同code>serial
实现:当手动提供值时,也需要手动调整底层序列 - 与
serial
列相同。默认情况下,标识列不是主键(就像
serial
列一样)。 如果应该是一个,则需要手动定义主键约束。Starting with Postgres 10, identity columns as defined by the SQL standard are also supported:
creates an identity column that can't be overridden unless explicitly asked for. The following insert will fail with a column defined as
generated always
:This can however be overruled:
When using the option
generated by default
this is essentially the same behaviour as the existingserial
implementation:When a value is supplied manually, the underlying sequence needs to be adjusted manually as well - the same as with a
serial
column.An identity column is not a primary key by default (just like a
serial
column). If it should be one, a primary key constraint needs to be defined manually.虽然看起来序列与 MySQL auto_increment 等效,但存在一些微妙但重要的区别:
1. 失败的查询递增序列/序列
序列列在失败的查询时递增。 这会导致查询失败而产生碎片,而不仅仅是行删除。 例如,在 PostgreSQL 数据库上运行以下查询:
您应该得到以下输出:
注意 uid 如何从 1 变为 3,而不是 1 到 2。
如果您要手动创建自己的序列,这种情况仍然会发生:
如果您愿意要测试 MySQL 的不同之处,请在 MySQL 数据库上运行以下命令:
在无碎片的情况下,您应该得到以下结果:
2. 手动设置串行列值可能会导致将来的查询失败。
@trev 在之前的回答中指出了这一点。
为了模拟这种情况,手动将 uid 设置为 4,稍后会发生“冲突”。
表数据:
运行另一个插入:
表数据:
现在如果您运行另一个插入:
它将失败并显示以下错误消息:
相反,MySQL 将优雅地处理此问题,如下所示:
现在插入另一行而不设置 uid
查询不会失败,uid 只是跳转到 5:
测试是在 MySQL 5.6.33、Linux (x86_64) 和 PostgreSQL 9.4 上执行的。 9
Whilst it looks like sequences are the equivalent to MySQL auto_increment, there are some subtle but important differences:
1. Failed Queries Increment The Sequence/Serial
The serial column gets incremented on failed queries. This leads to fragmentation from failed queries, not just row deletions. For example, run the following queries on your PostgreSQL database:
You should get the following output:
Notice how uid goes from 1 to 3 instead of 1 to 2.
This still occurs if you were to manually create your own sequence with:
If you wish to test how MySQL is different, run the following on a MySQL database:
You should get the following with no fragementation:
2. Manually Setting the Serial Column Value Can Cause Future Queries to Fail.
This was pointed out by @trev in a previous answer.
To simulate this manually set the uid to 4 which will "clash" later.
Table data:
Run another insert:
Table data:
Now if you run another insert:
It will fail with the following error message:
In contrast, MySQL will handle this gracefully as shown below:
Now insert another row without setting uid
The query doesn't fail, uid just jumps to 5:
Testing was performed on MySQL 5.6.33, for Linux (x86_64) and PostgreSQL 9.4.9
抱歉,要重复一个老问题,但这是 Google 上出现的第一个 Stack Overflow 问题/答案。
这篇文章(首先出现在 Google 上)讨论了如何使用 PostgreSQL 10 更新的语法:
https://blog.2ndquadrant.com/postgresql-10-identity-columns/
恰好是:
希望有帮助:)
Sorry, to rehash an old question, but this was the first Stack Overflow question/answer that popped up on Google.
This post (which came up first on Google) talks about using the more updated syntax for PostgreSQL 10:
https://blog.2ndquadrant.com/postgresql-10-identity-columns/
which happens to be:
Hope that helps :)
您必须小心不要直接插入到您的 SERIAL 或序列字段中,否则当序列达到插入的值时您的写入将失败:
You have to be careful not to insert directly into your SERIAL or sequence field, otherwise your write will fail when the sequence reaches the inserted value:
从 PostgreSQL 10 开始
Since PostgreSQL 10
在提出的问题的上下文中并回复@sereja1c的评论,创建
SERIAL
隐式创建序列,因此对于上面的示例-CREATE TABLE
将隐式创建序列< code>foo_id_seq 用于串行列foo.id
。 因此,SERIAL
[4 Bytes] 易于使用,除非您的 id 需要特定的数据类型。In the context of the asked question and in reply to the comment by @sereja1c, creating
SERIAL
implicitly creates sequences, so for the above example-CREATE TABLE
would implicitly create sequencefoo_id_seq
for serial columnfoo.id
. Hence,SERIAL
[4 Bytes] is good for its ease of use unless you need a specific datatype for your id.这种方法肯定有效,我希望它有所帮助:
您可以在下一个链接中查看详细信息:
http://www.postgresqltutorial.com/postgresql-serial/
This way will work for sure, I hope it helps:
You can check this the details in the next link:
http://www.postgresqltutorial.com/postgresql-serial/
创建序列。
并更改表
Create Sequence.
and alter table