约束 (Constraints)
用于规定表中的数据规则。如果存在违反约束的数据行为,行为会被约束终止。
约束可以在创建表时规定(通过 CREATE TABLE 语句),或者在表创建之后规定(通过 ALTER TABLE 语句)。
CREATE TABLE + CONSTRAINT语法:
CREATE TABLE table_name
(
column_name1 data_type(size) constraint_name,
column_name2 data_type(size) constraint_name,
column_name3 data_type(size) constraint_name,
....
);
主要有约束:NOT NULL,UNIQUE,PRIMARY KEY,FOREIGN KEY,CHECK,DEFAULT
1.NOT NULL :强制列不接受NULL(空)值
2.UNIQUE:约束唯一标识数据库表中的每条记录。
UNIQUE 和 PRIMARY KEY 约束均为列或列集合提供了唯一性的保证。
PRIMARY KEY 拥有自动定义的 UNIQUE 约束。
请注意,每个表可以有多个 UNIQUE 约束,但是每个表只能有一个 PRIMARY KEY 约束。
(1)在 "Persons" 表创建时在 "Id_P" 列创建 UNIQUE 约束
SQL Server / Oracle / MS Access:
注意:不同数据库,UNIQUE约束所在位置不同。
如果需要命名 UNIQUE 约束,以及为多个列定义 UNIQUE 约束,使用下面的SQL语法:
(2)当表已被创建时,如需在 "Id_P" 列创建 UNIQUE 约束
当表已被创建时,如需在 "Id_P" 列创建 UNIQUE 约束,通过使用ALTER TABLE语句修改,如下:
ALTER TABLE Persons ADD UNIQUE (Id_P)
如需命名 UNIQUE 约束,并定义多个列的 UNIQUE 约束:
ALTER TABLE PersonsADD CONSTRAINT uc_PersonID UNIQUE (Id_P,LastName)
(3)撤销 UNIQUE 约束
MySQL: ALTER TABLE Persons DROP INDEX uc_PersonID;
SQL Server / Oracle / MS Access: ALTER TABLE Persons DROP CONSTRAINT uc_PersonID;
3.PRIMARY KEY : 约束唯一标识数据库表中的每条记录。
主键必须包含唯一的值;主键列不能包含 NULL 值;每个表都应该有一个主键,并且每个表只能有一个主键。
(1)在 "Persons" 表创建时在 "Id_P" 列创建 PRIMARY KEY 约束:
如果需要命名 PRIMARY KEY 约束,以及为多个列定义 PRIMARY KEY 约束:
(2)在表已存在的情况下为 "Id_P" 列创建 PRIMARY KEY 约束:
ALTER TABLE Persons ADD PRIMARY KEY (Id_P);
如果需要命名 PRIMARY KEY 约束,以及为多个列定义 PRIMARY KEY 约束:
ALTER TABLE Persons ADD CONSTRAINT pk_PersonID PRIMARY KEY (Id_P,LastName)
(3)撤销 PRIMARY KEY 约束
MySQL: ALTER TABLE Persons DROP PRIMARY KEY
SQL Server / Oracle / MS Access: ALTER TABLE Persons DROP CONSTRAINT pk_PersonID
4.FOREIGN KEY:用于预防破坏表之间连接的动作,也能防止非法数据插入外键列,因为它必须是它指向的那个表中的值之一。
一个表中的 FOREIGN KEY 指向另一个表中的 PRIMARY KEY。(多对一的关系)
(1)在 "Orders" 表创建时为 "Id_P" 列创建 FOREIGN KEY:
如果需要命名 FOREIGN KEY 约束,以及为多个列定义 FOREIGN KEY 约束:
(2)在 "Orders" 表已存在的情况下为 "Id_P" 列创建 FOREIGN KEY 约束:
如果需要命名 FOREIGN KEY 约束,以及为多个列定义 FOREIGN KEY 约束:
(3)撤销 FOREIGN KEY 约束
5.CHECK:用于限制列中的值的范围
如果对单个列定义 CHECK 约束,那么该列只允许特定的值;如果对一个表定义 CHECK 约束,那么此约束会在特定的列中对值进行限制。
(1)在 "Persons" 表创建时为 "Id_P" 列创建 CHECK 约束。CHECK 约束规定 "Id_P" 列必须只包含大于 0 的整数。
如果需要命名 CHECK 约束,以及为多个列定义 CHECK 约束:
(2)在表已存在的情况下为 "Id_P" 列创建 CHECK 约束:
ALTER TABLE Persons ADD CHECK (Id_P>0);
如果需要命名 CHECK 约束,以及为多个列定义 CHECK 约束:
ALTER TABLE Persons ADD CONSTRAINT chk_Person CHECK (Id_P>0 AND City='Sandnes');
(3)撤销 CHECK 约束
MySQL: ALTER TABLE Persons DROP CHECK chk_Person;
SQL Server / Oracle / MS Access: ALTER TABLE Persons DROP CONSTRAINT chk_Person;
6.DEFAULT 约束:用于向列中插入默认值。如果没有规定其他的值,那么会将默认值添加到所有的新记录。
(1)在 "Persons" 表创建时为 "City" 列创建 DEFAULT 约束:
通过使用类似 GETDATE() 这样的函数,DEFAULT 约束也可以用于插入系统值:
(2)在表已存在的情况下为 "City" 列创建 DEFAULT 约束:
MySQL: ALTER TABLE Persons ALTER City SET DEFAULT 'SANDNES'
SQL Server / Oracle / MS Access: ALTER TABLE Persons ALTER COLUMN City SET DEFAULT 'SANDNES'
(3)撤销 DEFAULT 约束
MySQL: ALTER TABLE Persons ALTER City DROP DEFAULT
SQL Server / Oracle / MS Access: ALTER TABLE Persons ALTER COLUMN City DROP DEFAULT
CREATE INDEX 语句
用于在表中创建索引。在不读取整个表的情况下,索引使数据库应用程序可以更快地查找数据。
索引:
您可以在表中创建索引,以便更加快速高效地查询数据。
用户无法看到索引,它们只能被用来加速搜索/查询。
注释:更新一个包含索引的表需要比更新一个没有索引的表更多的时间,这是由于索引本身也需要更新。因此,理想的做法是仅仅在常常被搜索的列(以及表)上面创建索引。
1.CREATE INDEX 语法:
在表上创建一个简单的索引。允许使用重复的值:
CREATE INDEX index_name ON table_name (column_name)
CREATE UNIQUE INDEX 语法:
在表上创建一个唯一的索引。唯一的索引意味着两个行不能拥有相同的索引值。
CREATE UNIQUE INDEX index_name ON table_name (column_name)
注释:"column_name" 规定需要索引的列
CREATE INDEX 实例:
(1)在 Persons 表的 LastName 列,创建名为 "PersonIndex"的索引:
CREATE INDEX PersonIndex ON Persons (LastName)
(2)以降序索引某个列中的值:
CREATE INDEX PersonIndex ON Person (LastName DESC)
(3)索引多列:
CREATE INDEX PersonIndex ON Person (LastName, FirstName)
DROP 撤销索引、表以及数据库
DROP INDEX 语句:删除表格中的索引
语法:
MySQL: ALTER TABLE table_name DROP INDEX index_name
Microsoft SQLJet / Microsoft Access: DROP INDEX index_name ON table_name
MS SQL Server : DROP INDEX table_name.index_name
DROP TABLE 语句:用于删除表(表的结构、属性以及索引也会被删除)
语法:DROP TABLE 表名称
DROP DATABASE 语句:用于删除数据库
语法:DROP DATABASE 语句
TRUNCATE TABLE 语句:仅仅删除表格中的数据,但不删除表的结构
语法:TRUNCATE TABLE 表名称
SQL关于删除的三个语句:DROP、TRUNCATE、 DELETE 的区别:
相同点:drop、delete、truncate 都是删除表的内容。
不同点:
delete:删除表的内容,表的结构还存在,不释放空间,可以回滚恢复;
drop:删除表内容和结构,释放空间,没有备份表之前要慎用;
truncate:删除表的内容,表的结构存在,可以释放空间,没有备份表之前要慎用;
执行速度:drop > truncate > delete
ALTER TABLE 语句
用于在已有的表中添加、修改或删除列
1.添加列
ALTER TABLE table_name ADD column_name datatype
2.删除列
ALTER TABLE table_name DROP COLUMN column_name
注释:某些数据库系统不允许这种在数据库表中删除列的方式 (DROP COLUMN column_name)。
3.改变数据类型
ALTER TABLE table_name ALTER COLUMN column_name datatype
AUTO INCREMENT 字段
会在新纪录插入表时生成一个唯一的数字,可自动地创建主键字段的值
MySQL语法:
把 "Persons" 表中的 "P_Id" 列定义为 auto-increment 主键:
再插入新的记录时不必为 "P_Id" 列规定值,会自动添加唯一的值。
MySQL 使用 AUTO_INCREMENT 关键字来执行 auto-increment 任务,默认地开始值是 1,每条新记录递增 1。
要让 AUTO_INCREMENT 序列以其他的值起始,请使用下列 SQL 语法:
ALTER TABLE Persons AUTO_INCREMENT=100;
SQL Server 的语法:
要规定 "P_Id" 列以 20 起始且递增 10,请把 identity 改为 IDENTITY(20,10)。
Access 的语法:
规定 "P_Id" 列以 20 起始且递增10,请把 autoincrement 改为AUTOINCREMENT(20,10)。
VIEW(视图)
视图是基于 SQL 语句的结果集的可视化的表。
视图包含行和列,就像一个真实的表。视图中的字段就是来自一个或多个数据库中的真实的表中的字段。我们可以向视图添加 SQL 函数、WHERE 以及 JOIN 语句,我们也可以提交数据,就像这些来自于某个单一的表。
注释:数据库的设计和结构不会受到视图中的函数、where 或 join 语句的影响。
CREATE VIEW 语法:
CREATE VIEW view_name AS SELECT column_name(s) FROM table_name WHERE condition;
注释:视图总是显示最近的数据。每当用户查询视图时,数据库引擎通过使用 SQL 语句来重建数据。
NULL 值
是遗漏的未知数据,默认地,表的列可以存放 NULL 值。
如果表中的某个列是可选的,那么我们可以在不向该列添加值的情况下插入新记录或更新已有的记录。这意味着该字段将以 NULL 值保存。
NULL 值的处理方式与其他值不同。NULL 用作未知的或不适用的值的占位符。
注释:无法比较 NULL 和 0;它们是不等价的。
Persons表:
假如 "Persons" 表中的 "Address" 列是可选的。这意味着如果在 "Address" 列插入一条不带值的记录,"Address" 列会使用 NULL 值保存。
IS NULL
用来测试是否NULL值
要想选取Address列的NULL值记录,就需要使用IS NULL操作符,如:
SELECT LastName,FirstName,Address FROM Persons WHERE Address IS NULL
提示:请始终使用 IS NULL 来查找 NULL 值。因为无法使用比较运算符来测试 NULL 值,比如 =, <, 或者 <>。
IS NOT NULL
要想选取Address列中不是NULL值的记录,就需要使用IS NOT NULL操作符,如:
SELECT LastName,FirstName,Address FROM Persons WHERE Address IS NOT NULL
数据类型
MySQL 中有三种主要的类型:文本、数字和日期/时间类型。
TEXT文本类型:
Number类型:
注意:这些整数类型拥有额外的选项 UNSIGNED。通常,整数可以是负数或正数。如果添加 UNSIGNED 属性,那么范围将从 0 开始,而不是某个负数。
Date类型:
* 即便 DATETIME 和 TIMESTAMP 返回相同的格式,它们的工作方式很不同。在 INSERT 或 UPDATE 查询中,TIMESTAMP 自动把自身设置为当前的日期和时间。TIMESTAMP 也接受不同的格式,比如 YYYYMMDDHHMMSS、YYMMDDHHMMSS、YYYYMMDD 或 YYMMDD。
Microsoft Access/ SQL Server 数据类型,大家可以网上搜搜,我就不说了。
DATE 函数
当我们处理日期时,最难的任务恐怕是确保所插入的日期的格式,与数据库中日期列的格式相匹配。只要数据包含的只是日期部分,运行查询就不会出问题。但是,如果涉及时间,情况就有点复杂了。
在讨论日期查询的复杂性之前,我们先来看看最重要的内建日期处理函数。
MySQL内建重要date函数:
SQL Server:
Date 数据类型
MySQL 使用下列数据类型在数据库中存储日期或日期/时间值:
DATE - 格式 YYYY-MM-DD
DATETIME - 格式: YYYY-MM-DD HH:MM:SS
TIMESTAMP - 格式: YYYY-MM-DD HH:MM:SS
YEAR - 格式 YYYY 或 YY
SQL Server 使用下列数据类型在数据库中存储日期或日期/时间值:
DATE - 格式 YYYY-MM-DD
DATETIME - 格式: YYYY-MM-DD HH:MM:SS
SMALLDATETIME - 格式: YYYY-MM-DD HH:MM:SS
TIMESTAMP - 格式: 唯一的数字
日期处理
如果不涉及时间部分,那么我们可以轻松地比较两个日期!
假设我们有下面这个 "Orders" 表:
查询OrderDate是“2020-01-06”的记录:
SELECT * FROM Orders where orderdate='2020-01-06';
结果集
现在假设 "Orders" 类似这样(注意 "OrderDate" 列中的时间部分):
在使用上面的查询语句:
SELECT * FROM Orders where orderdate='2020-01-06';
这时我们得不到结果。因为该查询不含有时间部分的日期。
提示:如果您希望使查询简单且更易维护,那么请不要在日期中使用时间部分!
NULL 函数
ISNULL()、NVL()、IFNULL() 和 COALESCE() 函数
"Product"表:
假如 "UnitsOnOrder" 是可选的,而且可以包含 NULL 值。
SELECT ProductName,UnitPrice*(UnitsInStock+UnitsOnOrder) FROM Products;
上面查询语句中,如果有 "UnitsOnOrder" 值是 NULL,那么结果是 NULL,此时不利于计算,为了方便计算,我们将NULL值返回0即可,那么如何做呢?ISNULL(),NVL(), IFNULL() 和 COALESCE() 函数可以处理 NULL 值。如下:
MySQL:
SELECT ProductName,UnitPrice*(UnitsInStock+IFNULL(UnitsOnOrder,0)) FROM Products
或者我们可以使用 COALESCE() 函数,就像这样:
SELECT ProductName,UnitPrice*(UnitsInStock+COALESCE(UnitsOnOrder,0)) FROM Products
IFNULL判断是否为空,若为真返回0,否则返回当前值,Coalesce() 同理。
SQL Server / MS Access:
SELECT ProductName,UnitPrice*(UnitsInStock+ISNULL(UnitsOnOrder,0)) FROM Products
Oracle:
Oracle 没有 ISNULL() 函数。不过,我们可以使用 NVL() 函数达到相同的结果:
SELECT ProductName,UnitPrice*(UnitsInStock+NVL(UnitsOnOrder,0)) FROM Products
以上4个函数用法一样,不同数据库对应不同函数。
下篇就到函数啦~