你可以在一张表上拥有多个 UNIQUE 约束,但每张表只能有一个 PRIMARY KEY 约束。
索引与约束
约束
SQL 约束是对表列强制执行的规则。它们用于防止无效数据被输入到数据库中。
这确保了你的数据库中数据的准确性和可靠性。
默认值
DEFAULT 子句指定当执行 INSERT 时,如果用户未提供该列的值,则使用的默认值。
如果列定义中没有显式附加 DEFAULT 子句,那么该列的默认值为 NULL。
显式的 DEFAULT 子句可以指定默认值为 NULL、字符串常量、blob 常量、有符号数字,或任何用括号括起的常量表达式。
import { sql } from "drizzle-orm";
import { integer, sqliteTable } from "drizzle-orm/sqlite-core";
const table = sqliteTable('table', {
int1: integer('int1').default(42),
int2: integer('int2').default(sql`(abs(42))`)
});
CREATE TABLE `table` (
`int1` integer DEFAULT 42
`int2` integer DEFAULT (abs(42))
);非空
默认情况下,列可以保存 NULL 值。NOT NULL 约束强制列不接受 NULL 值。
这会强制某个字段始终包含一个值,这意味着你不能在不为该字段添加值的情况下插入新记录, 或更新记录。
const table = sqliteTable('table', {
numInt: integer('numInt').notNull()
});CREATE TABLE table (
`numInt` integer NOT NULL
);唯一
UNIQUE 约束确保列中的所有值都不同。
UNIQUE 和 PRIMARY KEY 约束都能保证某列或某组列的唯一性。
PRIMARY KEY 约束会自动具有 UNIQUE 约束。
import { int, text, unique, sqliteTable } from "drizzle-orm/sqlite-core";
export const user = sqliteTable('user', {
id: int('id').unique(),
});
export const table = sqliteTable('table', {
id: int('id').unique('custom_name'),
});
export const composite = sqliteTable('composite_example', {
id: int('id'),
name: text('name'),
}, (t) => [
unique().on(t.id, t.name),
unique('custom_name').on(t.id, t.name)
]);CREATE TABLE `user` (
`id` integer UNIQUE
);
CREATE TABLE `table` (
`id` integer CONSTRAINT `custom_name` UNIQUE
);
CREATE TABLE `composite_example` (
`id` integer,
`name` text,
CONSTRAINT `composite_example_id_name_unique` UNIQUE(`id`,`name`),
CONSTRAINT `custom_name` UNIQUE(`id`,`name`)
);检查
CHECK 约束用于限制可以放入某列的值范围。
如果你在列上定义 CHECK 约束,它将只允许该列使用某些特定值。
如果你在表上定义 CHECK 约束,它可以根据行中其他列的值来限制某些列中的值。
import { sql } from "drizzle-orm";
import { check, int, sqliteTable, text } from "drizzle-orm/sqlite-core";
export const users = sqliteTable(
"users",
{
id: int().primaryKey(),
username: text().notNull(),
age: int(),
},
(table) => [
check("age_check1", sql`${table.age} > 21`)
]
);CREATE TABLE `users` (
`id` integer PRIMARY KEY NOT NULL,
`username` text NOT NULL,
`age` integer,
CONSTRAINT "age_check1" CHECK("age" > 21)
);主键
PRIMARY KEY 约束可唯一标识表中的每条记录。
主键必须包含 UNIQUE 值,并且不能包含 NULL 值。
一张表只能有一个主键;而在表中,这个主键可以由单列或多列(字段)组成。
import { integer, sqliteTable } from "drizzle-orm/sqlite-core";
export const user = sqliteTable("user", {
id: integer().primaryKey({ autoIncrement: true }),
})
export const pet = sqliteTable("pet", {
id: integer().primaryKey(),
})CREATE TABLE `user` (
`id` integer PRIMARY KEY AUTOINCREMENT
);
CREATE TABLE `pet` (
`id` integer PRIMARY KEY
)复合主键
和 PRIMARY KEY 一样,复合主键通过使用多个字段来唯一标识表中的每条记录。
Drizzle ORM 为此提供了一个独立的 primaryKey 操作符:
import { integer, text, primaryKey, sqliteTable} from "drizzle-orm/sqlite-core";
export const user = sqliteTable("user", {
id: integer().primaryKey({ autoIncrement: true }),
name: text(),
});
export const book = sqliteTable("book", {
id: integer().primaryKey({ autoIncrement: true }),
name: text(),
});
export const bookToAuthor = sqliteTable("book_to_author", {
authorId: integer("author_id"),
bookId: integer("book_id"),
}, (table) => [
primaryKey({ columns: [table.bookId, table.authorId] }),
// 或使用自定义名称的主键
primaryKey({ name: 'custom_name', columns: [table.bookId, table.authorId] })
]);...
CREATE TABLE `book_to_author` (
`author_id` integer,
`book_id` integer,
PRIMARY KEY(`book_id`, `author_id`)
);外键
FOREIGN KEY 约束用于防止会破坏表之间关联的操作。
外键是某个表中的一个字段(或字段集合),它引用另一个表中的 PRIMARY KEY。
包含外键的表称为子表,被引用主键所在的表称为引用表或父表。
Drizzle ORM 提供了多种声明外键的方式。 你可以在列声明语句中声明它们:
import { integer, text, sqliteTable } from "drizzle-orm/sqlite-core";
export const user = sqliteTable("user", {
id: integer().primaryKey({ autoIncrement: true }),
name: text(),
});
export const book = sqliteTable("book", {
id: integer().primaryKey({ autoIncrement: true }),
name: text(),
authorId: integer("author_id").references(() => user.id)
});如果你想进行自引用,由于 TypeScript 的限制,你必须显式
为引用回调设置返回类型,或者使用独立的 foreignKey 操作符。
import { integer, text, foreignKey, sqliteTable, type AnySQLiteColumn } from "drizzle-orm/sqlite-core";
export const user = sqliteTable("user", {
id: integer().primaryKey({ autoIncrement: true }),
name: text(),
parentId: integer("parent_id").references((): AnySQLiteColumn => user.id)
});
//或
export const user = sqliteTable("user", {
id: integer().primaryKey({ autoIncrement: true }),
name: text(),
parentId: integer(),
}, (table) => [
foreignKey({
columns: [table.parentId],
foreignColumns: [table.id],
name: "custom_fk"
})
]);要声明多列外键,可以使用专用的 foreignKey 操作符:
import { integer, text, primaryKey, foreignKey, sqliteTable } from "drizzle-orm/sqlite-core";
export const user = sqliteTable("user", {
firstName: text("firstName"),
lastName: text("lastName"),
}, (table) => [
primaryKey({ columns: [table.firstName, table.lastName]})
]);
export const profile = sqliteTable("profile", {
id: integer().primaryKey({ autoIncrement: true }),
userFirstName: text("user_first_name"),
userLastName: text("user_last_name"),
}, (table) => [
foreignKey({
columns: [table.userFirstName, table.userLastName],
foreignColumns: [user.firstName, user.lastName],
name: "custom_name"
})
]);索引
Drizzle ORM 为 index 和 unique index 声明都提供了 API:
import { integer, text, index, uniqueIndex, sqliteTable } from "drizzle-orm/sqlite-core";
export const user = sqliteTable("user", {
id: integer().primaryKey({ autoIncrement: true }),
name: text(),
email: text(),
}, (table) => [
index("name_idx").on(table.name),
uniqueIndex("email_idx").on(table.email),
]);CREATE TABLE `user` (
...
);
CREATE INDEX `name_idx` ON `user` (`name`);
CREATE UNIQUE INDEX `email_idx` ON `user` (`email`);Drizzle ORM 为索引创建提供了一组完整的参数:
// 索引声明参考
index("name")
.on(table.name)
.where(sql`...`)