架构:
CREATE TABLE "applications" (
"id" SERIAL NOT NULL PRIMARY KEY,
"country" VARCHAR(2) NOT NULL,
"created" TIMESTAMP WITH TIME ZONE NOT NULL,
"is_preliminary" BOOLEAN NOT NULL,
"first_name" VARCHAR(128) NOT NULL,
"last_name" VARCHAR(128) NOT NULL,
"birth_number" VARCHAR(11) NULL
);
CREATE TABLE "persons" (
"id" UUID NOT NULL PRIMARY KEY,
"created" TIMESTAMP WITH TIME ZONE NOT NULL,
"modified" TIMESTAMP WITH TIME ZONE NOT NULL
);
ALTER TABLE "applications" ADD COLUMN "physical_person_id" UUID NULL;
CREATE INDEX "physical_person_id_idx" ON "applications" ("physical_person_id");
ALTER TABLE …Run Code Online (Sandbox Code Playgroud) 数据通过准备好的语句和存储过程进入我的应用程序,所以我不太担心注入。当新用户注册时,我想发送一封激活电子邮件。目前我正在使用触发器和通知来执行此操作。它看起来像这样:
CREATE FUNCTION on_sign_up() RETURNS trigger as $$
DECLARE
BEGIN
PERFORM pg_notify('sign_ups', NEW.user_id || ',' || NEW.email || ',' || NEW.activation_code);
RETURN new;
END;
$$ language plpgsql;
CREATE TRIGGER on_sign_up_trigger AFTER INSERT ON user_account
FOR EACH ROW EXECUTE PROCEDURE on_sign_up();
Run Code Online (Sandbox Code Playgroud)
我的问题是通知有效负载。如果电子邮件包含逗号,那么我不能只在 ',' 上拆分字符串。我如何转义任何东西并将其放入有效载荷中?我可以添加我自己的自定义 CSV 转义函数并调用它,但是每当我认为这样的事情是正确的答案时,我通常会遗漏一些东西。
它不一定需要是 CSV,我只是认为这是最简单的。
注意:还有其他解决方案 - 例如去除“前缀”和“后缀”,然后将其余部分视为电子邮件。我对 PostgreSQL 本身内部的这种一般的清理/转义类更感兴趣。
我试图提取的表格如下:
Table "user_account"
Column | Type | Modifiers
-----------------+---------+----------------------------
user_id | integer | not null
email | citext | not null
password_hash | text | not null …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用以下语句更新表中的多行:
update test as t set
column_a = c.column_a
from (values
('123', 1),
('345', 2)
) as c(column_b, column_a)
where c.column_b = t.column_b;
Run Code Online (Sandbox Code Playgroud)
但是,在我的数据库中 column_b 中的值不是唯一的(例如,多行可以有“123”)。我还有一个带有 DATE 类型的 column_c。对于更新语句中的每一行,我只希望上述更新发生在 column_c 中具有最新日期的行上,例如通过按日期对数据进行排序并使用 LIMIT 1。
因此,我试图将此查询与此处提供的答案结合起来。但是,我很难做到这一点。
我的数据库有 VARCHAR 列,每个列包含 20k-60k 不同的短文本。将这些值存储在每一行中是不可行的(由于空间限制),它们需要以某种方式外部化。这些值永远不会更新。
经典的方法是用单独的查找表和相应的 id 替换这些列中的每一个 - 然而,这需要大量的连接和大量类似的表。
枚举对于这个问题似乎不可行,尽管它们会消除显式连接的需要:它们不能超过 63 个字节,并且在版本 10 之前不可能在事务中添加新值。
我查看了 CREATE TABLE 的文档 - 似乎没有对这种重复数据删除的内置支持。TOAST-Tables 似乎也不包含唯一值。
我错过了另一种方法吗?
我正在创建一个 pre-prod Postgres 数据库,并希望确保访问用户具有有限的访问权限。
我想以这样的方式设置表的访问用户不能CREATE,DROP或ALTER对象。目前,我可以看到将所有权更改为另一个用户的唯一方法,例如postgres然后以某种方式仅授予所需的权限:
ALTER TABLE mytable SET OWNER TO postgres;
REVOKE connect ON DATABASE mydatabase FROM PUBLIC;
GRANT USAGE, SELECT, UPDATE ON ALL TABLES IN SCHEMA public TO dbuser;
GRANT connect ON DATABASE mydatabase TO dbuser;
Run Code Online (Sandbox Code Playgroud)
问题是当我执行上述操作SELECT时,当我与应用了授权的用户连接时,我无法做一个简单的事情。例如:
select * from mytable;
Run Code Online (Sandbox Code Playgroud)
产量:
Run Code Online (Sandbox Code Playgroud)ERROR: permission denied for relation mytable
如何做到这一点?
此外,我应该使用public?以外的命名模式吗?
我正在尝试从本地 postgres 数据库双表中选择 now():
select now() from dual;
Run Code Online (Sandbox Code Playgroud)
它不返回任何行。只打印列名now(yyyy-MM-dd HH:mm:ss.ffffff)
我错过了什么无法获得系统时间?
如何检查 PostgreSQL 9.1 中的碎片?
我试图找出位于矩形区域(信封)内的点。我在使用了一点点难度的理解性能影响&&运营商相比ST_Intersect。
但是,我想我在尝试提出我的问题时解释了我自己的问题。我无论如何都会提交它,以防它对某人有用。
&&的手册说(具有讽刺意味的是,页面名称是 geometry_overlaps.html):
&& — 如果 A 的 2D 边界框与 B 的 2D 边界框相交,则返回 TRUE。`
ST_Intersects的手册说:
如果几何/地理“在二维空间上相交”-(共享空间的任何部分),则返回 TRUE,如果不相交(它们不相交),则返回 FALSE。对于地理 - 容差为 0.00001 米(因此任何靠近的点都被视为相交)
ST_Intersects在这种情况下将返回 true。因为我&&在任何一种情况下都使用矩形边界框,所以我的目标运算符几乎做同样的事情。我想知道是否&&是我的目的最快的运营商?感觉&&必须做更少的检查,所以它必须更有效率。
这是一个直接复制自&&,ST_Intersects改编的示例:
SELECT
t1.id AS t1,
t2.id AS t2,
t1.ln && t2.ln AS "&&",
ST_Intersects(t1.ln,t2.ln)
FROM ( VALUES
(1, 'LINESTRING(0 0, 3 3)'::geometry),
(2, 'LINESTRING(0 1, 0 5)'::geometry)
) AS t1(id,ln)
CROSS JOIN (VALUES
(3, 'LINESTRING(1 2, 4 …Run Code Online (Sandbox Code Playgroud) ICU 指定不同的LDML 整理设置。其中一些看起来很有趣,尤其是关于大小写和口音的那些,
- “忽略重音”:
strength=primary- “忽略重音”但要考虑大小写:
strength=primary caseLevel=on- “忽略大小写”:
strength=secondary- “忽略标点符号”(完全):
strength=tertiary alternate=shifted- “忽略标点符号”但区分标点符号:
strength=quaternary alternate=shifted可能是更好的做事方法
您还可以在此处查看这些文档。PostgreSQL 10 ICU 整理支持是否可以使用这些 ICU 选项和设置?
CREATE COLLATION special (provider = icu, locale = 'en@strength=primary');
SELECT 'Å' LIKE 'A' COLLATE "special"; # returns false
Run Code Online (Sandbox Code Playgroud)
我也试过CLDR BCP47
从 ICU 54 开始,排序规则属性也可以通过语言环境关键字指定,使用旧的语言环境扩展语法 ("
el@colCaseFirst=upper") 或语言标记语法 ("el-u-kf-upper")。关键字和值不区分大小写。请参阅LDML 归类规范、归类设置和列出有效归类关键字及其值的数据文件。(不支持已弃用的属性 kh/colHiraganaQuaternary 和 vt/variableTop。)
为此,这看起来是对的
CREATE COLLATION special (provider = icu, locale = 'en-ks-level1');
SELECT …Run Code Online (Sandbox Code Playgroud) postgresql collation postgresql-10 international-components-unicode
postgresql ×10
postgis ×2
spatial ×2
collation ×1
csv ×1
international-components-unicode ×1
json ×1
performance ×1
permissions ×1
select ×1
subquery ×1
timestamp ×1