更新时间:2022-12-18 13:31:35
将原始混合大小写字符串存储在纯文本列中。使用数据类型 文本
或 varchar
而不使用长度修饰符,而不是 VARCHAR(n)的
。它们基本上是一样的,但是使用varchar(n),你必须设置一个任意的长度限制,如果你想稍后改变,这可能会很痛苦。详细了解手册或本相关答案由Peter Eisentraut @ serverfault.SE 。
创建一个 功能唯一索引 C $ C>下(字符串)。这是主要的一点:
CREATE UNIQUE INDEX my_idx ON mytbl(lower(name));
如果您尝试 INSERT
这个名字已经在小写上,你会得到一个唯一的密钥违规错误。
对于快速的等式搜索使用这样的查询:
SELECT * FROM mytbl WHERE lower(name)='foo' - 'foo'是小写的,当然。
使用与索引中相同的表达式(因此查询计划程序可以识别兼容性)非常快。
另外,您可能需要升级到PostgreSQL的最新版本。自8.4.2以来,已有大量重要修复程序。有关官方Postgres版本控制网站的更多信息。
I have basically a username is unique (case insensitive), but the case matters when displaying as provided by the user.
I have the following requirements:
Is this possible in Django?
The only solution I came up with is "somehow" override the Model manager, use an extra field, or always use 'iexact' in searches.
I'm on Django 1.3 and PostgreSQL 8.4.2.
Store the original mixed-case string in a plain text column. Use the data type text
or varchar
without length modifier rather than varchar(n)
. They are essentially the same, but with varchar(n) you have to set an arbitrary length limit, that can be a pain if you want to change later. Read more about that in the manual or in this related answer by Peter Eisentraut @serverfault.SE.
Create a functional unique index on lower(string)
. That's the major point here:
CREATE UNIQUE INDEX my_idx ON mytbl(lower(name));
If you try to INSERT
a mixed case name that's already there in lower case you get a unique key violation error.
For fast equality searches use a query like this:
SELECT * FROM mytbl WHERE lower(name) = 'foo' --'foo' is lower case, of course.
Use the same expression you have in the index (so the query planner recognizes the compatibility) and this will be very fast.
As an aside: you may want to upgrade to a more recent version of PostgreSQL. There have been lots of important fixes since 8.4.2. More on the official Postgres versioning site.