Files
lab/go/projects/lyra/docs/demo.sql
T
labmem e4fc4af912 feat(lyra): 添加 PostgreSQL 初始化示例
- 定义用户、分类和链接表,包含密码哈希字段
- 添加数据约束、索引及更新时间触发器
2026-10-16 17:40:01 +08:00

131 lines
5.2 KiB
PL/PgSQL

-- Polaris 导航站 PostgreSQL 新库初始化示例(非幂等,仅执行一次)。
BEGIN;
-- updated_at 维护函数
CREATE FUNCTION public.set_updated_at()
RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
NEW.updated_at := now();
RETURN NEW;
END;
$$;
-- 用户表
CREATE TABLE public.users (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
account text NOT NULL UNIQUE,
password_hash text NOT NULL,
display_name text NOT NULL,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
CONSTRAINT users_account_not_empty CHECK (btrim(account) <> ''),
CONSTRAINT users_display_name_not_empty CHECK (btrim(display_name) <> '')
);
COMMENT ON TABLE public.users IS '后台管理用户表';
COMMENT ON COLUMN public.users.id IS '用户 ID';
COMMENT ON COLUMN public.users.account IS '登录账号,当前大小写敏感';
COMMENT ON COLUMN public.users.password_hash IS '密码哈希';
COMMENT ON COLUMN public.users.display_name IS '展示昵称';
COMMENT ON COLUMN public.users.created_at IS '创建时间';
COMMENT ON COLUMN public.users.updated_at IS '更新时间,触发器自动刷新';
-- 分类表
CREATE TABLE public.categories (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
slug text NOT NULL UNIQUE,
title text NOT NULL,
description text NOT NULL DEFAULT '',
icon text NOT NULL,
sort integer NOT NULL DEFAULT 0,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
CONSTRAINT categories_slug_format CHECK (slug ~ '^[a-z0-9]+(-[a-z0-9]+)*$'),
CONSTRAINT categories_title_not_empty CHECK (btrim(title) <> '')
);
COMMENT ON TABLE public.categories IS '链接分类表';
COMMENT ON COLUMN public.categories.id IS '分类 ID,内部关联用';
COMMENT ON COLUMN public.categories.slug IS '页面地址(路由)标识';
COMMENT ON COLUMN public.categories.title IS '分类标题';
COMMENT ON COLUMN public.categories.description IS '分类描述';
COMMENT ON COLUMN public.categories.icon IS '分类图标标识';
COMMENT ON COLUMN public.categories.sort IS '分类排序,越小越靠前';
COMMENT ON COLUMN public.categories.created_at IS '创建时间';
COMMENT ON COLUMN public.categories.updated_at IS '更新时间,触发器自动刷新';
-- 链接表
CREATE TABLE public.links (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
category_id bigint NOT NULL,
title text NOT NULL,
description text NOT NULL DEFAULT '',
url text NOT NULL,
icon text,
keywords text[] NOT NULL DEFAULT ARRAY[]::text[],
sort integer NOT NULL DEFAULT 0,
pinned boolean NOT NULL DEFAULT false,
pinned_sort integer,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
CONSTRAINT links_category_fk
FOREIGN KEY (category_id) REFERENCES public.categories (id)
ON DELETE RESTRICT,
CONSTRAINT links_title_not_empty CHECK (btrim(title) <> ''),
CONSTRAINT links_url_not_empty CHECK (btrim(url) <> ''),
CONSTRAINT links_pinned_sort_consistent CHECK (pinned = (pinned_sort IS NOT NULL)),
CONSTRAINT links_keywords_one_dimension
CHECK (cardinality(keywords) = 0 OR array_ndims(keywords) = 1),
CONSTRAINT links_keywords_no_null_elements
CHECK (array_position(keywords, NULL) IS NULL)
);
COMMENT ON TABLE public.links IS '链接表,归属分类';
COMMENT ON COLUMN public.links.id IS '链接 ID';
COMMENT ON COLUMN public.links.category_id IS '所属分类 ID,删分类前需先处理链接';
COMMENT ON COLUMN public.links.title IS '链接标题';
COMMENT ON COLUMN public.links.description IS '链接描述';
COMMENT ON COLUMN public.links.url IS '链接地址,应用层校验,去尾斜杠后全局唯一';
COMMENT ON COLUMN public.links.icon IS '链接图标,可空,前端回退';
COMMENT ON COLUMN public.links.keywords IS '搜索关键词数组,供本地搜索匹配';
COMMENT ON COLUMN public.links.sort IS '分类内排序,越小越靠前';
COMMENT ON COLUMN public.links.pinned IS '首页快捷入口(手动固定),非点击排行';
COMMENT ON COLUMN public.links.pinned_sort IS '首页快捷入口顺序,越小越靠前';
COMMENT ON COLUMN public.links.created_at IS '创建时间';
COMMENT ON COLUMN public.links.updated_at IS '更新时间,触发器自动刷新';
-- 索引
CREATE INDEX categories_order_idx
ON public.categories (sort, id);
CREATE INDEX links_category_order_idx
ON public.links (category_id, sort, id);
CREATE INDEX links_pinned_order_idx
ON public.links (pinned_sort, id)
WHERE pinned;
CREATE UNIQUE INDEX links_normalized_url_unique
ON public.links (rtrim(url, '/'));
-- 触发器
CREATE TRIGGER users_set_updated_at
BEFORE UPDATE ON public.users
FOR EACH ROW
EXECUTE FUNCTION public.set_updated_at();
CREATE TRIGGER categories_set_updated_at
BEFORE UPDATE ON public.categories
FOR EACH ROW
EXECUTE FUNCTION public.set_updated_at();
CREATE TRIGGER links_set_updated_at
BEFORE UPDATE ON public.links
FOR EACH ROW
EXECUTE FUNCTION public.set_updated_at();
COMMIT;