小编Joh*_*and的帖子

如何在PostgreSQL(或一般的SQL)中实现业务逻辑权限?

假设我有一个项目表:

CREATE TABLE items
(
    item serial PRIMARY KEY,
    ...
);
Run Code Online (Sandbox Code Playgroud)

现在,我想为每个项目介绍“权限”的概念(请注意,我在这里不是在谈论数据库访问权限,而是该项目的业务逻辑权限)。每个项目都具有默认权限以及可以覆盖默认权限的每用户权限。

我试图想出几种方法来实现这一点,并提出了以下解决方案,但我不确定哪个是最好的以及为什么:

1) 布尔解决方案

为每个权限使用布尔列:

CREATE TABLE items
(
    item serial PRIMARY KEY,

    can_change_description boolean NOT NULL,
    can_change_price boolean NOT NULL,
    can_delete_item_from_store boolean NOT NULL,
    ...
);

CREATE TABLE item_per_user_permissions
(
    item int NOT NULL REFERENCES items(item),
    user int NOT NULL REFERENCES users(user),

    PRIMARY KEY(item, user),

    can_change_description boolean NOT NULL,
    can_change_price boolean NOT NULL,
    can_delete_item_from_store boolean NOT NULL,
    ...
);
Run Code Online (Sandbox Code Playgroud)

优点:每个权限都是命名的。

缺点:有几十个权限会显着增加列数,并且您必须定义它们两次(每个表中一次)。

2)整数解

使用整数并将其视为位域(即位 0 …

postgresql enum

19
推荐指数
2
解决办法
7438
查看次数

如何以扩展的树状方式对递归查询的结果进行排序?

假设您有这样的nodes表:

CREATE TABLE nodes
(
    node serial PRIMARY KEY,
    parent integer NULL REFERENCES nodes(node),
    ts timestamp NOT NULL DEFAULT now()
);
Run Code Online (Sandbox Code Playgroud)

它代表了一个标准的类似节点的树结构,根节点在顶部,几个子节点悬挂在根节点或其他子节点上。

让我们插入几个示例值:

INSERT INTO nodes (parent)
VALUES (NULL), (NULL), (NULL), (NULL), (1), (1), (1), (1), (6), (1)
     , (6), (9), (6), (6), (3), (3), (3), (15);
Run Code Online (Sandbox Code Playgroud)

现在我想检索前 10 个根节点及其所有子节点,深度为 4:

WITH RECURSIVE node_rec AS
(
    (SELECT 1 AS depth, * FROM nodes WHERE parent IS NULL LIMIT 10)

    UNION ALL

    SELECT depth + 1, n.*
    FROM nodes …
Run Code Online (Sandbox Code Playgroud)

postgresql cte order-by recursive

14
推荐指数
1
解决办法
1万
查看次数

这里有什么更好的 - 单列或多列主键?

假设您有一张桌子groups和一张桌子item。每个项目都属于一个组。它是该群体的固有组成部分。一个项目不能存在于一个组之外,也不能移动到另一个组中。

当试图决定item表的主键时,我应该使用什么?

我应该像这样组成一个人工全局序列键:

CREATE TABLE items
(
    item serial PRIMARY KEY,
    group integer NOT NULL REFERENCES groups(group),
);
Run Code Online (Sandbox Code Playgroud)

...或者我应该使用复合键和每组项目序列,如下所示:

CREATE TABLE items
(
    group integer NOT NULL REFERENCES groups(group),
    item integer NOT NULL,

    PRIMARY KEY(group, item)
);
Run Code Online (Sandbox Code Playgroud)

我更倾向于第二种解决方案的原因是帖子 URL 将始终显示组项目,因此将它们都作为复合主键是有意义的。在第一种解决方案的情况下,URL 包含多余的信息,因为组 ID 已经可以单独从项目 ID 中推导出来。但是,URL 结构是给定的,不能更改。

第二种解决方案的缺点是您必须管理每个组的序列(即每个组的每个项目整数应从 0 开始)。

在最佳实践、规范化和性能方面哪个更好?或者这只是品味问题?

postgresql database-design best-practices primary-key

2
推荐指数
1
解决办法
1701
查看次数