如何只允许一个表的一行?

Posted

技术标签:

【中文标题】如何只允许一个表的一行?【英文标题】:How to allow only one row for a table? 【发布时间】:2014-08-14 11:43:01 【问题描述】:

我有一张表,我希望只有一个条目。因此,如果有人试图插入另一行,则只有在有人删除了先前存在的行之后才允许插入另一行。

如何为这样的表格设置规则?

【问题讨论】:

【参考方案1】:

UNIQUE 约束允许具有NULL 值的多行,因为两个NULL 值永远不会被视为相同。

类似的考虑适用于CHECK 约束。它们允许表达式为TRUENULL(只是不是FALSE)。同样,NULL 值通过了检查。

要排除这种情况,列必须定义为NOT NULL。或者将其设为 PRIMARY KEY,因为 PK 列是自动定义的 NOT NULL。详情:

Why can I create a table with PRIMARY KEY on a nullable column?

另外,只需使用boolean

CREATE TABLE public.onerow (
   onerow_id bool PRIMARY KEY DEFAULT TRUE
 , data text
 , CONSTRAINT onerow_uni CHECK (onerow_id)
);

CHECK 约束对于boolean 列来说就这么简单。只允许TRUE

您可能需要REVOKE(或不GRANT)来自public(和所有其他角色)的DELETETRUNCATE 权限,以防止单行被删除。喜欢:

REVOKE DELETE, TRUNCATE ON public.onerow FROM public;

【讨论】:

【参考方案2】:

向表中添加一个新列,然后在该列上添加一个检查约束和唯一性约束。例如:

CREATE TABLE logging (
    LogId integer UNIQUE default(1),
    MyData text,
    OtherStuff numeric,
    Constraint CHK_Logging_singlerow CHECK (LogId = 1)
);

现在您只能拥有一个 LogId = 1 的行。如果您尝试添加新行,它将破坏唯一性或检查约束。

(我可能弄乱了语法,但它给了你一个想法?)

【讨论】:

UNIQUE 约束允许(多个)NULL 值,因此这是不安全。我的答案中的详细信息。 好的,我检查了这个,PostgreSQL 的工作方式与 SQL Server 不同; SQL Server 只允许一个 NULL 值(在我看来这是一个更明智的实现)。无论如何,这都是无关紧要的,因为这个想法是在创建新行时不指定 LogId,这会将值设置为默认值 1,这不是 NULL,所以这并不重要吗?但是,如果我们非常迂腐,我想定义应该是 NOT NULL :P 有两种数据库管理员:一种是“迂腐的”,另一种是在 SO 上发布关于神秘“损坏”的数据库的绝望问题。 :p【参考方案3】:

您应该在此表上创建一个ON BEFORE INSERT 触发器。在触发器上,调用检查count(*) 的过程,当计数为 1 时,它会向用户返回异常消息,否则允许插入继续。

查看this documentation 以获取示例。

【讨论】:

可能,但比必要的要昂贵和复杂。 你的方法行得通,毫无疑问,是的,这更贵。我只是提供了一个无需更改表格即可工作的解决方案。 当这不是您要插入的表时,为什么要花费这么多钱(不止一次;大概这样的表的目的是存储单例)像配置)?从美学上讲,这对我来说肯定更令人愉快,因为您不需要与存储的数据无关的列和检查。

以上是关于如何只允许一个表的一行?的主要内容,如果未能解决你的问题,请参考以下文章

JQuery DataTables:如何显示/隐藏多个表的行详细信息?

SQL Server 存储过程只返回临时表的最后一行

如何设置ssh安全只允许用户从指定的IP登陆

Django 迁移:如何只允许在 --fake 模式下运行?

MySQL返回连接表的第一行

来自数据库的 PEAR MIME html 表只发送一行