PostgreSQL 约束用于规定表中的数据规则。
如果存在违反约束的数据行为,行为会被约束终止。
约束可以在创建表时规定(通过 CREATE TABLE 语句),或者在表创建之后规定(通过 ALTER TABLE 语句)。
约束确保了数据库中数据的准确性和可靠性。
约束可以是列级或表级。列级约束仅适用于列,表级约束被应用到整个表。
以下是在 PostgreSQL 中常用的约束。
默认情况下,列可以保存为 NULL 值。如果您不想某列有 NULL 值,那么需要在该列上定义此约束,指定在该列上不允许 NULL 值。
NULL 与没有数据是不一样的,它代表着未知的数据。
实例
下面实例创建了一张新表叫 COMPANY1,添加了 5 个字段,其中三个 ID,NAME,AGE 设置不接受空置:
CREATE TABLE COMPANY1( ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50), SALARY REAL );
UNIQUE 约束可以设置列是唯一的,避免同一列出现重复值。
实例
下面实例创建了一张新表叫 COMPANY3,添加了 5 个字段,其中 AGE 设置为 UNIQUE,因此你不能添加两条有相同年龄的记录:
CREATE TABLE COMPANY3( ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL UNIQUE, ADDRESS CHAR(50), SALARY REAL DEFAULT 50000.00 );
在设计数据库时,PRIMARY KEY 非常重要。
PRIMARY KEY 称为主键,是数据表中每一条记录的唯一标识。
设置 UNIQUE 的列可能有多个,但是一张表只有一列可以设置 PRIMARY KEY。
我们可以使用主键来引用表中的行,也可以通过把主键设置为其他表的外键,来创建表之间的关系。
主键是非空约束和唯一约束的组合。
一个表只能有一个主键,它可以由一个或多个字段组成,当多个字段作为主键,它们被称为复合键。
如果一个表在任何字段上定义了一个主键,那么在这些字段上不能有两个记录具有相同的值。
实例
下面我们创建 COMAPNY4 表,其中 ID 作为主键:
CREATE TABLE COMPANY4( ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50), SALARY REAL );
FOREIGN KEY 即外键约束,指定列(或一组列)中的值必须匹配另一个表的某一行中出现的值。
通常一个表中的 FOREIGN KEY 指向另一个表中的 UNIQUE KEY(唯一约束的键),即维护了两个相关表之间的引用完整性。
实例
下面实例创建了一张 COMPANY6 表,并添加了5个字段:
CREATE TABLE COMPANY6( ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50), SALARY REAL );
下面实例创建一张 DEPARTMENT1 表,并添加 3 个字段,EMP_ID 就是外键,参照 COMPANY6 的 ID:
CREATE TABLE DEPARTMENT1( ID INT PRIMARY KEY NOT NULL, DEPT CHAR(50) NOT NULL, EMP_ID INT references COMPANY6(ID) );
CHECK 约束保证列中的所有值满足某一条件,即对输入一条记录要进行检查。如果条件值为 false,则记录违反了约束,且不能输入到表。
实例
例如,下面实例建一个新的表 COMPANY5,增加了五列。在这里,我们为 SALARY 列添加 CHECK,所以工资不能为零:
CREATE TABLE COMPANY5( ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50), SALARY REAL CHECK(SALARY > 0) );
EXCLUSION 约束确保如果使用指定的运算符在指定列或表达式上比较任意两行,至少其中一个运算符比较将返回 false 或 null。
实例
下面实例创建了一张 COMPANY7 表,添加 5 个字段,并且使用了 EXCLUDE 约束。
CREATE TABLE COMPANY7( ID INT PRIMARY KEY NOT NULL, NAME TEXT, AGE INT , ADDRESS CHAR(50), SALARY REAL, EXCLUDE USING gist (NAME WITH =, -- 如果满足 NAME 相同,AGE 不相同则不允许插入,否则允许插入 AGE WITH <>) -- 其比较的结果是如果整个表边式返回 true,则不允许插入,否则允许 );
这里,USING gist 是用于构建和执行的索引一种类型。
您需要为每个数据库执行一次 CREATE EXTENSION btree_gist 命令,这将安装 btree_gist 扩展,它定义了对纯标量数据类型的 EXCLUDE 约束。
由于我们已经强制执行了年龄必须相同,让我们通过向表插入记录来查看这一点:
INSERT INTO COMPANY7 VALUES(1, 'Paul', 32, 'California', 20000.00 ); INSERT INTO COMPANY7 VALUES(2, 'Paul', 32, 'Texas', 20000.00 ); -- 此条数据的 NAME 与第一条相同,且 AGE 与第一条也相同,故满足插入条件 INSERT INTO COMPANY7 VALUES(3, 'Allen', 42, 'California', 20000.00 ); -- 此数据与上面数据的 NAME 相同,但 AGE 不相同,故不允许插入
前面两条顺利添加的 COMPANY7 表中,但是第三条则会报错:
ERROR: conflicting key value violates exclusion constraint "company7_name_age_excl" DETAIL: Key (name, age)=(Paul, 42) conflicts with existing key (name, age)=(Paul, 32).
删除约束必须知道约束名称,已经知道名称来删除约束很简单,如果不知道名称,则需要找到系统生成的名称,使用 \d 表名 可以找到这些信息。
通用语法如下:
ALTER TABLE table_name DROP CONSTRAINT some_name;
我已经找到了几个使用datamapper的示例,并且能够让它们正常工作。不过,所有这些示例都是针对sqlite数据库的。我正在尝试将数据映射器与postgresql一起使用。我将datamapper中的调用从sqlite3更改为postgres,并且我已经安装了dm-postgres-adapter。但它仍然不起作用。我还需要做什么? 最佳答案 与SQLite不同,PostgreSQL不将数据库存储在单个文件中。在你拥有createdyourdatabase之后,尝试这样的事情:DataMapper.setup:default,{:
我找到了这样的东西:Rails:Howtolistdatabasetables/objectsusingtheRailsconsole?这一行没问题:ActiveRecord::Base.connection.tables并返回所有表但是ActiveRecord::Base.connection.table_structure("users")产生错误:ActiveRecord::Base.connection.table_structure("projects")我认为table_structure不是Postgres方法。如何列出Postgres数据库的Rails控制台中表中的所有
我想使用PostgreSQL中的point类型。我已经完成了:railsgmodelTestpoint:point最终的迁移是:classCreateTests当我运行时:rakedb:migrate结果是:==CreateTests:migrating====================================================--create_table(:tests)rakeaborted!Anerrorhasoccurred,thisandalllatermigrationscanceled:undefinedmethod`point'for#/hom
我正在使用带有单个“帐户”表的STI模型来保存用户和技术人员的信息(即用户...8)错误:test_the_truth(用户测试):ActiveRecord::StatementInvalid:PGError:ERROR:关系“技术人员”不存在:从“技术人员”中删除...从本质上讲,标准框架不承认Technicians和Users表(或PostgreSQL称它们为“关系”)不存在,事实上,应该别名为Accounts。有什么想法吗?我对RoR比较陌生,不知道如何解决这个问题而又不完全删除STI。 最佳答案 原来问题是由于存在:./te
我正在使用PostgreSQL9.1.3(x86_64-pc-linux-gnu上的PostgreSQL9.1.3,由gcc-4.6.real(Ubuntu/Linaro4.6.1-9ubuntu3)4.6.1,64位编译)和在ubuntu11.10上运行3.2.2或3.2.1。现在,我可以使用以下命令连接PostgreSQLsupostgres输入密码我可以看到postgres=#我将以下详细信息放在我的config/database.yml中并执行“railsdb”,它工作正常。开发:adapter:postgresqlencoding:utf8reconnect:falsedat
我有一个数据库表列(collection),datatypetext我在collection中插入了json数据这是我的json数据{"name":"test","age":"25","country":"xxx"}但是现在我该如何查询这个json数据。有没有如下选项User.where(collection::name)#Herenamedenotestest 最佳答案 由于JSON是一个字符串,您只能使用SQLite/MySQL(或任何其他数据库)进行字符串比较。此外,尽量将数据类型保持为二进制。您可以执行:LIKE操作以在您存
我在两个不同的模式中有两个表,例如案例和事件。在每个模式中我都有基本表events.basiccases.basic这个表有关系:events.basic有一个cases.basic(cases.basic有多个events.basic)我的尝试失败了:文件cases_basic.rbclassCasesBasic'EventsBasic',:foreign_key=>'case_id'end文件events_basic.rbclassEventsBasic'CasesBasic',:foreign_key=>'case_id'end环境:Ruby1.9.3、Rails3.1.3、ge
我的迁移看起来像这样classCreateQuestionings现在,当我运行$rakedb:migrate:reset时,在我的db/schema.rb中看不到限制:create_table"questionings",force::cascadedo|t|t.text"body",null:falseend我做错了吗还是这是一个错误?顺便说一下,我使用的是rails5.0.0.beta3和ruby2.3.0p0。 最佳答案 t.text在PostgreSQL和textdoesn'tallowforsizelimits中生成
文章目录前言约束硬约束的轨迹优化Corridor-BasedTrajectoryOptimizationBezierCurveOptimizationOtherOptions软约束的轨迹优化Distance-BasedTrajectoryOptimization优化方法前言可以看看我的这几篇Blog1,Blog2,Blog3。上次基于MinimumSnap的轨迹生成,有许多优点,比如:轨迹让机器人可以在某个时间点抵达某个航点。任何一个时刻,都能数学上求出期望的机器人的位置、速度、加速度、导数。MinimumSnap可以把问题转换为凸优化问题。缺点:MnimumSnap可以控制轨迹一定经过中间的
我在postgresql中有一个表,其中包含一些汽车+1000000条记录:+----+--------+------+---------+-----------+-------------+------------+------------+|id|price|year|mileage|fuel_type|body_type|brand|model|+----+--------+------+---------+-----------+-------------+------------+------------+|1|4894|2011|121842|"Benzin"|"Sedan