Postgresql 是否可以创建始终为小写的char列?
我想创建一个如下表:Postgresql 是否可以创建始终为小写的char列?,postgresql,Postgresql,我想创建一个如下表: create table project_types ( id char(20) not null unique default 'xxx' }; 要将其从其他表中使用,请执行以下操作: create table other_table ( ... fk_ptype char(20), fk_ptype_on_other_table" foreign key (fk_ptype) references project_type(id) ); 问题是,我希
create table project_types (
id char(20) not null unique default 'xxx'
};
要将其从其他表中使用,请执行以下操作:
create table other_table (
...
fk_ptype char(20),
fk_ptype_on_other_table" foreign key (fk_ptype) references project_type(id)
);
问题是,我希望插入到project_type
中的所有值都自动变为小写:我不希望对每个可能的查询进行转换,我希望有一个表,无论我对它抛出什么,它都返回小写标记
我正在考虑在更新时插入一个触发器,但我想知道是否有更好的方法来施加这样的限制。此外,这个解决方案意味着我必须在删除时进行转换
对于那些可能建议我使用enum的类型:类型是动态的,所以我更喜欢这种方法
更新2017.04.17:这个问题的想法不是将控件/转换放在堆栈中的每一个地方:如果数据库可以处理您向它抛出的任何东西,那么您不必1。在前端检查/转换,2。在后端代码中检查/转换,最后是3。在数据库中检查/转换。您只需避免执行1和2,因为您知道数据库将处理您向它抛出的任何内容,并且当您从中选择时,您将获得正确的数据
我很想选择答案,但似乎相同的方法无法用于删除(我尝试使用相同的函数设置和删除触发器,但没有起作用)。:
:
如何在插入或更新之前使用触发器,以确保/转换数据小写
CREATE OR REPLACE FUNCTION public.fun_trg_lowercase()
RETURNS trigger AS
$BODY$
begin
NEW.my_char_field = lowercase(NEW.my_char_field);
RETURN NEW;
end;
$BODY$
LANGUAGE plpgsql VOLATILE;
CREATE TRIGGER biu_lowercase_field
BEFORE INSERT OR UPDATE
ON mytable
FOR EACH ROW
EXECUTE PROCEDURE fun_trg_lowercase();
如何在插入或更新之前使用触发器,以确保/转换数据小写
CREATE OR REPLACE FUNCTION public.fun_trg_lowercase()
RETURNS trigger AS
$BODY$
begin
NEW.my_char_field = lowercase(NEW.my_char_field);
RETURN NEW;
end;
$BODY$
LANGUAGE plpgsql VOLATILE;
CREATE TRIGGER biu_lowercase_field
BEFORE INSERT OR UPDATE
ON mytable
FOR EACH ROW
EXECUTE PROCEDURE fun_trg_lowercase();
为此,您可以使用一种特殊类型的数据,称为
CITEXT
(=不区分大小写的文本)。它是PostgreSQL中额外提供的模块标准
引用:
F.8.1。理由
例如,在PostgreSQL中进行不区分大小写匹配的标准方法是在比较值时使用lower函数
SELECT * FROM tab WHERE lower(col) = LOWER(?);
这项工作相当不错,但也有一些缺点:
这会使SQL语句变得冗长,并且您必须始终记住在列和查询值上使用lower
它不会使用索引,除非您使用lower创建函数索引
如果将列声明为唯一
或主键
,则隐式生成的索引区分大小写。因此,它对于不区分大小写的搜索是无用的,并且它不会在不区分大小写的情况下强制唯一性
citext数据类型允许您在SQL查询中消除对lower的调用,并允许主键不区分大小写。citext与文本一样具有区域设置意识,这意味着大写和小写字符的匹配取决于数据库的LC_CTYPE设置规则。同样,此行为与使用lower in查询相同。但是因为它是由数据类型透明地完成的,所以您不必记住在查询中执行任何特殊操作
因此,在您的具体情况下,您只需要:
一次:
CREATE EXTENSION citext ;
CREATE TABLE project_types
(
id citext PRIMARY KEY default 'xxx'
);
CREATE TABLE other_table
(
/* ... */
fk_ptype citext,
fk_ptype_on_other_table foreign key (fk_ptype) references project_type(id)
);
。。。然后,对您的查询不做任何处理。没有任何额外的约束,也没有任何(明显令人害怕的)触发器。为此,您可以使用一种特殊类型的数据,称为
CITEXT
(=不区分大小写的文本)。它是PostgreSQL中额外提供的模块标准
引用:
F.8.1。理由
例如,在PostgreSQL中进行不区分大小写匹配的标准方法是在比较值时使用lower函数
SELECT * FROM tab WHERE lower(col) = LOWER(?);
这项工作相当不错,但也有一些缺点:
这会使SQL语句变得冗长,并且您必须始终记住在列和查询值上使用lower
它不会使用索引,除非您使用lower创建函数索引
如果将列声明为唯一
或主键
,则隐式生成的索引区分大小写。因此,它对于不区分大小写的搜索是无用的,并且它不会在不区分大小写的情况下强制唯一性
citext数据类型允许您在SQL查询中消除对lower的调用,并允许主键不区分大小写。citext与文本一样具有区域设置意识,这意味着大写和小写字符的匹配取决于数据库的LC_CTYPE设置规则。同样,此行为与使用lower in查询相同。但是因为它是由数据类型透明地完成的,所以您不必记住在查询中执行任何特殊操作
因此,在您的具体情况下,您只需要:
一次:
CREATE EXTENSION citext ;
CREATE TABLE project_types
(
id citext PRIMARY KEY default 'xxx'
);
CREATE TABLE other_table
(
/* ... */
fk_ptype citext,
fk_ptype_on_other_table foreign key (fk_ptype) references project_type(id)
);
。。。然后,对您的查询不做任何处理。没有任何额外的约束,也没有任何(显然令人害怕的)触发器。他想要自动更改案例,所以需要触发器或触发器rules@VaoTsun这是答案的一半,因为触发器不太可靠。@ClodoaldoNeto:为什么触发器不可靠?@joanolo,因为程序员不可靠。@joanolo可能是的。但是更改或删除约束是设计更改,但是临时禁用触发器通常不被认为是设计更改(这样做并不罕见)。我并不是说触发器解决方案无效,但在OP的情况下,将此逻辑放在应用程序的存储库层要容易得多。db中的约束可以进行完整性检查。他想要自动改变大小写,所以需要触发器或rules@VaoTsun这是答案的一半,因为触发器不太可靠。@ClodoaldoNeto:为什么触发器不可靠?@joanolo,因为程序员不可靠。@joanolo可能是的。但是改变或删除约束是设计更改,但暂时禁用触发器通常不被视为一个(这样做并不罕见)。我并不是说触发器解决方案无效,但在OP的情况下,将此逻辑放在应用程序的存储库层要容易得多。