假设我有一个项目表:
CREATE TABLE items
(
item serial PRIMARY KEY,
...
);
Run Code Online (Sandbox Code Playgroud)
现在,我想为每个项目介绍“权限”的概念(请注意,我在这里不是在谈论数据库访问权限,而是该项目的业务逻辑权限)。每个项目都具有默认权限以及可以覆盖默认权限的每用户权限。
我试图想出几种方法来实现这一点,并提出了以下解决方案,但我不确定哪个是最好的以及为什么:
为每个权限使用布尔列:
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)
优点:每个权限都是命名的。
缺点:有几十个权限会显着增加列数,并且您必须定义它们两次(每个表中一次)。
使用整数并将其视为位域(即位 0 …
因此,我与同事关于使用枚举与查找表存在分歧。
这篇 2011 年和 MySQL5.5 的非常老的文章仍然被那些不喜欢枚举的人一次又一次地引用。
但我们使用的是 MySQL8.0,数据库规模不是很大,比如 50 到 60 个表,有 30 左右的枚举列。
一些表的行数高达数百万行,大多数表的行数远低于 50 万行。
几乎所有枚举的值都少于 10 个,并且只有极少数在其生命周期中发生过更改(一次),总是在可能值的末尾添加新值。
而且我们从未“遭受”文章提到的任何缺点,例如将元数据存储在其旁边,引用其他表中的相同值等......
尽管文章在第 2 点中提到了这一点,但今天,在列表末尾添加值不会更新整个表,但删除值总是会更新(或至少读取)所有行。
我确实知道有两种流派,并且我了解两者的优点和缺点。
但是,今天在 MySQL8 上,是否存在任何实际/事实/技术原因,因此 ** 放弃现有列的枚举并证明应用程序和数据库中所需的所有工作都是合理的?
感谢您的阅读和回答。
我有几个 SQL 对象,它们需要根据请求的所需状态采取备用操作。有没有办法创建可以传递给存储过程、表值函数并在查询中使用(不使用 CLR)的数据库级常量(枚举)?
CREATE PROCEDURE dbo.DoSomeWork(@param1 INTEGER, ..., @EnumValue myEnumType) AS ...;
Run Code Online (Sandbox Code Playgroud)
然后使用它:
EXEC doSomeWork 85, ..., (myEnumType.EnumValue1 + myEnumType.EnumValue2);
Run Code Online (Sandbox Code Playgroud)
哪里myEnumType会保存一些枚举值。
在该过程中,我将能够使用@EnumValue它并针对其中的值对其进行测试myEnumType以完成所需的工作。我会myEnumType为我正在考虑的情况设置位掩码的值。
举一个简单的例子,考虑一个昂贵的过程,它需要一个巨大的数据集,并将其缩减为一个较小但仍然非常大的数据集。在这个过程中,您需要在该过程中进行一些会影响结果的调整。假设这是根据减少中的中间计算的某些状态过滤(或反对)某些类型的记录。该@EnumValue类型的myEnumType可以用来测试此
SELECT ...
FROM ...
WHERE (@EnumValue & myEnumType.EnumValue1 = myEnumType.EnumValue1 AND ...)
OR (@EnumValue & myEnumType.EnumValue2 = myEnumType.EnumValue2 AND ...)
OR ...
Run Code Online (Sandbox Code Playgroud)
在不使用 CLR 的情况下,SQL Server 中是否可以使用这些类型的数据库级常量?
我正在寻找可以作为参数传递给存储过程、函数等的数据库级枚举或常量集。
我在当前存储为 VARCHAR 的 Postgres 数据库中有一个非常基本的分类列。我可以选择每个计数:
我虽然添加一个ORDER BY array_position()会做到这一点:
SELECT color, count(*)
FROM research
GROUP BY color
ORDER BY array_position(ARRAY['Red','Orange','Yellow','Green','Blue'], color);
Run Code Online (Sandbox Code Playgroud)
但我看到一个类型错误:
ERROR: function array_position(text[], character varying) does not exist
SQL state: 42883
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
Character: 98
Run Code Online (Sandbox Code Playgroud)
我需要投射什么color才能使用该array_position功能对其进行排序?
有没有办法确定 PostgreSQL 中的用户定义类型是否是 ENUM?
基本上我们有以下几点:
CREATE TYPE foo AS ENUM (
'Sometimes',
'You',
'Wanna',
'Go',
'Where Everybody Knows Your Name'
);
Run Code Online (Sandbox Code Playgroud)
通过以下方式实例化的表:
CREATE TABLE bar (
lyrics foo DEFAULT 'Wanna'::foo
);
Run Code Online (Sandbox Code Playgroud)
我能够foo从列中确定的类型lyrics,但是,我无法找到确定是否foo是 ENUM 的方法。
对于上下文,我需要此信息以编程方式获取foo给定lyrics.
在 MySQL 中使用下表:
CREATE TABLE bob(foo ENUM('a','b','c'));
INSERT INTO bob (foo) VALUES ('a'),('b'),('c'),('a'),('a');
SELECT * FROM bob WHERE foo >= 2;
+------+
| foo |
+------+
| b |
| c |
+------+
Run Code Online (Sandbox Code Playgroud)
使用 PostGres 中的下表:
CREATE TYPE stuff AS ENUM ('a', 'b', 'c');
INSERT INTO bob (foo) VALUES ('a'), ('b'), ('b'), ('c'), ('c');
SELECT * FROM bob WHERE foo > 2;
(HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.) …Run Code Online (Sandbox Code Playgroud) 假设我们有订单表,并且订单有状态。这三个选项中哪一个最好?
varchar状态栏enum状态栏status_id int和name varchar,并且在订单表中保留status_id作为外键。哪种方法是最好的?int我怀疑使用字典表也更好,因为通过, 而不是 来搜索状态会更快varchar。
我们运行 Dynamics GP,任何处理过 GP 的人都会熟悉它的所有“幻数”列,这些列代表应用程序内的各种枚举值。例如,报告查询可能如下所示:
...
WHERE sod.SOPTYPE = 2
AND iv.VCTNMTHD = 3
AND pod.POLNESTA IN (2, 3)
Run Code Online (Sandbox Code Playgroud)
......这与自我记录尽可能远。
起初我有一个聪明的想法,即创建一个名为“Enums”的表,用值填充它,并制作一个标量包装函数,这样你就可以像这样查询:
...
WHERE sod.SOPTYPE = Enum('Sales Doc Type', 'Order')
AND iv.VCTNMTHD = Enum('Valuation Method', 'Average Perpetual')
AND pod.POLNESTA IN (Enum('PO Line State', 'Released'), Enum('PO Line State', 'Change Order'))
Run Code Online (Sandbox Code Playgroud)
当然,这很糟糕,因为优化器无法看到潜在的“常量”值,因此做出了一些相当糟糕的选择,因为它必须进行基数猜测。
所以它需要是代码中的实际常量值,但我不确定 SSMS 中是否有任何很好的功能可以使这种事情变得容易。我可以(错误地)以某种方式使用代码片段或模板吗?如果我们可以进行某种查找/插入来使我们的代码看起来像这样,那就太棒了:
...
WHERE sod.SOPTYPE = /*Order*/2
AND iv.VCTNMTHD = /*Average Perpetual*/3
AND pod.POLNESTA IN (/*Released*/2, /*Change Order*/3)
Run Code Online (Sandbox Code Playgroud)
我也不反对检查 SSMS 加载项。
BRIN 索引似乎很有用,但我不确定如何在 ENUM 类型上使用。我认为这段代码会起作用:
CREATE TYPE test_enum AS ENUM ('a', 'b');
CREATE TEMPORARY TABLE my_table (
x test_enum
);
CREATE INDEX test_index ON my_table using brin (x);
ERROR: data type test_enum has no default operator class for access method "brin"
Run Code Online (Sandbox Code Playgroud)
我是否必须从头开始创建一个新的运算符类?枚举不是已经订购了吗?
这个提交,从 2014 开始,意味着 BRIN 索引应该适用于 ENUM 类型。
我正在尝试为我的 CIS 课程完成一项作业,我需要包含一个名为 ENUM 的数据类型。我知道这代表枚举列表,但我不确定何时是使用 ENUM 的合适时机。我正在使用的书中给出的几个例子就像一个大陆列表。我可以用它来描述工作场所的部门列表吗?