提问人:D Jake 提问时间:2/28/2013 更新时间:6/1/2014 访问量:6164
对序列列的引用 (PostgreSQL)
reference to a sequence column (postgresql)
问:
我在创建引用序列的外键时遇到了问题,请参阅下面的代码示例。
但是在创建表时,我收到以下错误。
“详细信息:关键列”product“和”id“的类型不兼容:integer 和 ownseq”
我已经为产品列尝试了不同的数据类型(如 smallint、bigint),但没有一个被接受。
CREATE SEQUENCE ownseq INCREMENET BY 1 MINVALUE 100 MAXVALUE 99999;
CREATE TABLE products (
id ownseq PRIMARY KEY,
...);
CREATE TABLE basket (
basket_id SERIAL PRIMARY KEY,
product INTEGER FOREIGN KEY REFERENCES products(id));
答:
CREATE SEQUENCE ownseq INCREMENT BY 1 MINVALUE 100 MAXVALUE 99999;
CREATE TABLE products (
id integer PRIMARY KEY default nextval('ownseq'),
...
);
alter sequence ownseq owned by products.id;
关键的变化是将其定义为 ,而不是 。如果使用伪类型创建序列,则会出现这种情况。id
integer
ownseq
SERIAL
尝试
CREATE TABLE products (
id INTEGER DEFAULT nextval(('ownseq'::text)::regclass) NOT NULL PRIMARY KEY,
...);
或者不要创建序列 ownseq 并让 postgres 为您完成:
CREATE TABLE products (
id SERIAL NOT NULL PRIMARY KEY
...);
在上述情况下,postgres 创建的序列的名称应该是 。products_id_seq
希望这会有所帮助。
评论
primary key
这意味着,后者是没有必要的。not null
regclass
serial
CREATE SEQUENCE tablename_colname_seq
PostgreSQL 功能强大,您刚刚被一项高级功能所吸引。
你的DDL是相当有效的,但根本不是你想象的那样。
序列可以看作是用于为某些列生成下一个值的事务外简单表。
你打算做什么
您的意思是将 id 字段定义为这样,根据另一个答案:
id integer PRIMARY KEY default nextval('ownseq'),
你做了什么
您所做的实际上是为表定义嵌套数据结构。假设我创建了一个测试序列:
CREATE SEQUENCE testseq;
然后假设我在 Pg 9.1 上,我得到:\d testseq
Sequence "public.testseq"
Column | Type | Value
---------------+---------+---------------------
sequence_name | name | testseq
last_value | bigint | 1
start_value | bigint | 1
increment_by | bigint | 1
max_value | bigint | 9223372036854775807
min_value | bigint | 1
cache_value | bigint | 1
log_cnt | bigint | 0
is_cycled | boolean | f
is_called | boolean | f
这是序列所用类型的定义。
现在假设我:
create table seqtest (test testseq, id serial);
我可以插入其中:
INSERT INTO seqtest (id, test) values (default, '("testseq",3,4,1,133445,1,1,0,f,f)');
然后,我可以从中进行选择:
select * from seqtest;
test | id
----------------------------------+----
(testseq,3,4,1,133445,1,1,0,f,f) | 2
此外,我可以扩展测试:
SELECT (test).* from seqtest;
select (test).* from seqtest;
sequence_name | last_value | start_value | increment_by | max_value | min_value
| cache_value | log_cnt | is_cycled | is_called
---------------+------------+-------------+--------------+-----------+----------
-+-------------+---------+-----------+-----------
| | | | |
| | | |
testseq | 3 | 4 | 1 | 133445 | 1
| 1 | 0 | f | f
(2 rows)
这种东西实际上在PostgreSQL中非常强大,但充满了意想不到的角落(例如,not null和check约束在嵌套数据类型中不能按预期工作)。我通常不推荐嵌套数据类型,但值得一提的是,PostgreSQL 可以做到这一点,并且很乐意接受 SQL 命令来做到这一点,而不会发出警告。
上一个:计算对序列进行排序的最小交换次数
下一个:递归导致的分段错误
评论