Ale*_*nch 3 sql database postgresql database-schema postgresql-9.3
我有一个 PostgreSQL 9.3 数据库,其中有一个用户表,该表以保留大小写的格式存储用户名。所有查询都不区分大小写,因此我应该有一个支持它的索引。此外,无论大小写,用户名都必须是唯一的。
这就是我想出的:
forum=> \d users
Table "public.users"
Column | Type | Modifiers
------------+--------------------------+------------------------
name | character varying(24) | not null
Indexes:
"users_lower_idx" UNIQUE, btree (lower(name::text))
Run Code Online (Sandbox Code Playgroud)
用标准 SQL 语法表示:
CREATE TABLE users (
name varchar(24) NOT NULL
);
CREATE UNIQUE INDEX "users_lower_idx" ON users (lower(name));
Run Code Online (Sandbox Code Playgroud)
通过这个模式,我已经满足了所有的约束,尽管没有主键。SQL 标准不支持功能主键,因此我无法提升索引:
forum=> ALTER TABLE users ADD PRIMARY KEY USING INDEX users_lower_idx;
ERROR: index "users_lower_idx" contains expressions
LINE 1: ALTER TABLE users ADD PRIMARY KEY USING INDEX users_lower_id...
^
DETAIL: Cannot create a primary key or unique constraint using such an index.
Run Code Online (Sandbox Code Playgroud)
但是,我已经有了 UNIQUE 约束,并且该列已经标记为“NOT NULL”。如果我必须有一个主键,我可以像这样构造表:
CREATE TABLE users (
name varchar(24) PRIMARY KEY
);
CREATE UNIQUE INDEX "users_lower_idx" ON users (lower(name));
Run Code Online (Sandbox Code Playgroud)
但这样我就会有两个索引,这对我来说似乎很浪费而且没有必要。那么,PRIMARY KEY 对 postgres 来说除了“UNIQUE NOT NULL”之外还有什么特别的意义吗?我是否因为没有 PRIMARY KEY 而错过了什么?
首先,几乎每个表都应该有一个主键。
citext附加模块提供同名的数据类型。“ci”不区分大小写。根据文档:
该
citext模块提供了不区分大小写的字符串类型,citext. 本质上,它lower在比较值时在内部调用。否则,它的行为几乎与 完全相同text。
它的目的正是您所描述的目的:
该
citext数据类型允许您消除 SQL 查询中对 lower 的调用,并允许主键不区分大小写。
大胆强调我的。
请务必先阅读有关限制的手册。每个数据库安装一次
CREATE EXTENSION citext;
Run Code Online (Sandbox Code Playgroud)
text如果您不想走这条路,我建议您添加一个serial作为代理主键。
CREATE TABLE users (
user_id serial PRIMARY KEY
, username text NOT NULL
);
Run Code Online (Sandbox Code Playgroud)
我会用text而不是varchar(24). CHECK如果需要强制执行最大长度(稍后可能会更改),请使用约束。细节:
以及UNIQUE原始设计中的索引(没有类型转换):
CREATE UNIQUE INDEX users_username_lower_idx ON users (lower(username));
Run Code Online (Sandbox Code Playgroud)
integera 的底层serial小而快,不必浪费时间lower()或数据库的排序规则。这对于外键引用特别有用。我更喜欢它而不是一些具有不同属性的自然主键。
两种解决方案都有优点和缺点。