专栏首页AustinDatabasesPostgreSQL 唯一约束与唯一索引 是一个人吗?

PostgreSQL 唯一约束与唯一索引 是一个人吗?

大部分数据库表都有一个承接的功能就是某个表每条记录的唯一性,通过唯一性来保证这张表的数据是不重复的。使用的场景很多,例如银行,每个人只能开一个1类账户,怎么来保证所有的人来银行开账户都是第一个账户,如果不是就不进行记录,而走下一个流程去二类账户。

这里讨论的不是二类账户,而是怎么能让这个承接类账户的表仅仅只能保存唯一的一个人一次的申请。这里有几种方法,

1 每次来一个人进行账户申请,我们都差一次遍历这张表的身份证号,如果查到这个身份证号,就不给他录入,如果没有就录入。

2 建立身份证号字段的唯一性,只要有重复就没法插入

1 和 2 的方法之间的差异是 1 方法是要程序来做判断,在极个别的情况下,是不能保证这个表的100%的唯一性。方法2 则是通过数据库的方式,节省了程序查询的时间,如果有重复就直接报错了,然后反馈给程序信心,程序会进行下一步的操作。

大部分情况下,开发都倾向于方法2 ,所以就有今天的话题,POSTGRESQL 的唯一约束与唯一索引,之间到底有什么区别,用哪个更好的满足开发的需求。

废话不说,我们来建立两个表,分别来看看

CREATE TABLE public.account_unique

( user_id integer NOT NULL DEFAULT nextval('account_user_id_seq'::regclass),

username character varying(50) COLLATE pg_catalog."default" NOT NULL,

password character varying(50) COLLATE pg_catalog."default" NOT NULL,

email character varying(355) COLLATE pg_catalog."default" NOT NULL,

created_on timestamp without time zone NOT NULL,

last_login timestamp without time zone,

CONSTRAINT account_unique_pkey PRIMARY KEY (user_id)

)

WITH (

OIDS = FALSE

)

TABLESPACE pg_default;

建两张同样表结构的表

create unique index IX_account_unique_email on account_unique (email);

alter table account_constrain add constraint unique_account_constrain_email unique(email);

同样往两张表中插入相同的数据都不能继续插入。

我们可以看到两个表,虽然功能都能达到,但采用的方法是不同的。

那么到底这两种方法有什么不同,或者有什么适用点。

首先我们使用了最常用的功能,判断插入的一行是否和现在的数据冲突,记过两种方式都是可以的,并且都可以在有重复插入与唯一索引,或约束定义的字段冲突的时候,不进行任何的数据的插入操作。

当然在设计表的时候,无法是约束还是唯一索引如果你设置的表的字段都可以为null 则这个不属于约束和唯一索引控制的范畴,会存在多个NULL的存在。

通过查询相关的文档和一些专业网站的建议,其实这两者在最后的结果上并不会有太多的差异,并且速度也是一致,或差不多的,因为建立一个约束时其实在后台就已经开始建立一个唯一索引了。只不过可能在索引的角度你看不到罢了。

这里更倾向于唯一索引的建立来替代约束,原因是如果你要进行删除约束的操作,是不会有concurrently 的操作命令,这样给清理约束带来的难度(大表)是比较难的。

同时POSTGRESQL 的索引的建立也是可以添加WHERE条件的,所以灵活性比约束要高。

实际上要说约束和唯一索引的不同点更多的时候是在应用与逻辑的层面去理解,约束更偏向于逻辑层面,是对数据的唯一性,或者其他特性的一种制约,相对于唯一索引,相关的面要多,例如你可以设置约束为只能输入的数据为大于1000的数字,这也可以叫约束。但一般来说如果是唯一性来说,还是可以建立唯一索引来更好的解决问题,查阅相关的一些资料也指明,POSTGRESQL 的唯一约束也是在列上建立了唯一索引,但是不可见的,当然你也可以建立唯一索引,在建立约束,通过挂接的方式让约束使用唯一索引。当然大部分数据库建立了唯一索引后,都会有性能上的损失或者死锁加重的一些情况(高频的访问),那天可以找一期来说说唯一索引对POSTGRESQL 数据库造成的一些影响。

本文分享自微信公众号 - AustinDatabases(AustinDatabases)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-10-08

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • CLR查找和加载程序集的方式(一)

      C#开发者在开发WinForm程序、Asp.Net Web(MVC)程序等,不可避免的在项目中引用许多第三方的DLL程序集,

    张传宁老师
  • MySQL Explain关键字

    使用 EXPLAIN 关键字可以模拟优化器执行 SQL 查询语句,从而知道 MySQL 是如何处理你的 SQL 语句的。分析你的查询语句或是表结构的性能瓶颈。

    万能青年
  • SQL反模式学习笔记21 SQL注入

      通常所说的“SQL动态查询”是指将程序中的变量和基本SQL语句拼接成一个完整的查询语句。

    张传宁老师
  • MySQL登录验证的抓包

    http://blog.chinaunix.net/uid-9234131-id-5088292.html

    二狗不要跑
  • 重磅推出:AutoProject Studio 自动化项目生成器

    AutoProject Studio 自动化项目生成器是一款基于C#.Net Framework 4.0为平台自主研发、专为软件 设计、开发、管理的自动化项目...

    张传宁老师
  • ​数据库|传统的集合运算

    关系R和关系5具有相同的目n(即两个关系都有n个属性),且相应的属性取自同一个域,则关系R与关系S的并由属于R或属于S的元组组成,其结果关系仍为n目关系。

    算法与编程之美
  • python操作数据库

    下载地址:https://pypi.python.org/pypi/MySQL-python/1.2.5 安装到系统即可。

    二狗不要跑
  • wordpress网站基于avada主题搬家教程

    今天给一个8核16G的服务器安装了宝塔和wordpress网站,第一次遇到这么高配置的服务器,记录一下。同时遇到关于wordpress网站基于avada主题搬家...

    wordpress建站吧
  • MySQL备份时候排除指定的数据库

    使用mysqldump命令备份时候,--all-databases 可以备份所有的数据库。 使用ignore-table 还可以排除制定的表。但是,mysqld...

    二狗不要跑
  • 架构秘笈:移花接木。使用mysql模拟redis

    这年头,你看到的东西未必就是你认为的东西。一个mysql协议的后面,可能是tidb;一个linux机器后面,可能是一个精简的docker;你觉得xjjdog是个...

    xjjdog

扫码关注云+社区

领取腾讯云代金券