01-02菜鸟教程第二部分

MariaDB [my_db]> select * from websites;
+----+---------------+---------------------------+-------+---------+
| id | name          | url                       | alexa | country |
+----+---------------+---------------------------+-------+---------+
|  1 | Google        | https://www.google.cm/    |     1 | USA     |
|  2 | 淘宝          | https://www.taobao.com/   |    13 | CN      |
|  3 | 菜鸟教程      | http://www.runoob.com/    |  5000 | USA     |
|  4 | 微博          | http://weibo.com/         |    20 | CN      |
|  5 | Facebook      | https://www.facebook.com/ |     3 | USA     |
|  7 | stackoverflow | http://stackoverflow.com/ |     0 | IND     |
+----+---------------+---------------------------+-------+---------+
6 rows in set (0.00 sec)

MariaDB [my_db]> select * from access_log;
+-----+---------+-------+------------+
| aid | site_id | count | date       |
+-----+---------+-------+------------+
|   1 |       1 |    45 | 2016-05-10 |
|   2 |       3 |   100 | 2016-05-13 |
|   3 |       1 |   230 | 2016-05-14 |
|   4 |       2 |    10 | 2016-05-14 |
|   5 |       5 |   205 | 2016-05-14 |
|   6 |       4 |    13 | 2016-05-15 |
|   7 |       3 |   220 | 2016-05-15 |
|   8 |       5 |   545 | 2016-05-16 |
|   9 |       3 |   201 | 2016-05-17 |
+-----+---------+-------+------------+



SQL JOIN
SQL JOIN 子句用于把来自两个或多个表的行结合起来,基于这些表之间的共同字段。
最常见的 JOIN 类型:SQL INNER JOIN(简单的 JOIN)。 SQL INNER JOIN 从多个表中返回满足 JOIN 条件的所有行。
MariaDB [my_db]> select websites.id, websites.name, access_log.count, access_log.date from websites
    -> inner join access_log
    -> on websites.id=access_log.site_id;
+----+--------------+-------+------------+
| id | name         | count | date       |
+----+--------------+-------+------------+
|  1 | Google       |    45 | 2016-05-10 |
|  1 | Google       |   230 | 2016-05-14 |
|  2 | 淘宝         |    10 | 2016-05-14 |
|  3 | 菜鸟教程     |   100 | 2016-05-13 |
|  3 | 菜鸟教程     |   220 | 2016-05-15 |
|  3 | 菜鸟教程     |   201 | 2016-05-17 |
|  4 | 微博         |    13 | 2016-05-15 |
|  5 | Facebook     |   205 | 2016-05-14 |
|  5 | Facebook     |   545 | 2016-05-16 |
+----+--------------+-------+------------+

MariaDB [my_db]> select * from websites inner join access_log on websites.id=access_log.site_id;
+----+--------------+---------------------------+-------+---------+-----+---------+-------+------------+
| id | name         | url                       | alexa | country | aid | site_id | count | date       |
+----+--------------+---------------------------+-------+---------+-----+---------+-------+------------+
|  1 | Google       | https://www.google.cm/    |     1 | USA     |   1 |       1 |    45 | 2016-05-10 |
|  1 | Google       | https://www.google.cm/    |     1 | USA     |   3 |       1 |   230 | 2016-05-14 |
|  2 | 淘宝         | https://www.taobao.com/   |    13 | CN      |   4 |       2 |    10 | 2016-05-14 |
|  3 | 菜鸟教程     | http://www.runoob.com/    |  5000 | USA     |   2 |       3 |   100 | 2016-05-13 |
|  3 | 菜鸟教程     | http://www.runoob.com/    |  5000 | USA     |   7 |       3 |   220 | 2016-05-15 |
|  3 | 菜鸟教程     | http://www.runoob.com/    |  5000 | USA     |   9 |       3 |   201 | 2016-05-17 |
|  4 | 微博         | http://weibo.com/         |    20 | CN      |   6 |       4 |    13 | 2016-05-15 |
|  5 | Facebook     | https://www.facebook.com/ |     3 | USA     |   5 |       5 |   205 | 2016-05-14 |
|  5 | Facebook     | https://www.facebook.com/ |     3 | USA     |   8 |       5 |   545 | 2016-05-16 |
+----+--------------+---------------------------+-------+---------+-----+---------+-------+------------+

不同的 SQL JOIN
在我们继续讲解实例之前,我们先列出您可以使用的不同的 SQL JOIN 类型:
INNER JOIN:如果表中有至少一个匹配,则返回行
LEFT JOIN:即使右表中没有匹配,也从左表返回所有的行
RIGHT JOIN:即使左表中没有匹配,也从右表返回所有的行
FULL JOIN:只要其中一个表中存在匹配,则返回行


首先,连接的结果可以在逻辑上看作是由SELECT语句指定的列组成的新表。
左连接与右连接的左右指的是以两张表中的哪一张为基准,它们都是外连接。
外连接就好像是为非基准表添加了一行全为空值的万能行,用来与基准表中找不到匹配的行进行匹配。假设两个没有空值的表进行左连接,左表是基准表,左表的所有行都出现在结果中,右表则可能因为无法与基准表匹配而出现是空值的字段。

在使用 join 时,on 和 where 条件的区别如下:
 1、 on 条件是在生成临时表时使用的条件,它不管 on 中的条件是否为真,都会返回左边表中的记录。
 2、where 条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有 left join 的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉。
详细内容可以查看:SQL JOIN 中 on 与 where 的区别
http://www.runoob.com/w3cnote/sql-join-the-different-of-on-and-where.html

---------------------------------------------------------------
SQL LEFT JOIN 关键字
LEFT JOIN 关键字从左表(table1)返回所有的行,即使右表(table2)中没有匹配。如果右表中没有匹配,则结果为 NULL。
SQL LEFT JOIN 语法
SELECT column_name(s)
FROM table1
LEFT JOIN table2
ON table1.column_name=table2.column_name;
或:
SELECT column_name(s)
FROM table1
LEFT OUTER JOIN table2
ON table1.column_name=table2.column_name;
注释:在某些数据库中,LEFT JOIN 称为 LEFT OUTER JOIN。

MariaDB [my_db]> select websites.name, access_log.count, access_log.date from websites left join access_log on websites.id=access_log.site_id order by access_log.count;

----------------------------------------------------------------------
SQL RIGHT JOIN 关键字
RIGHT JOIN 关键字从右表(table2)返回所有的行,即使左表(table1)中没有匹配。如果左表中没有匹配,则结果为 NULL。
SQL RIGHT JOIN 语法
SELECT column_name(s)
FROM table1
RIGHT JOIN table2
ON table1.column_name=table2.column_name;
或:
SELECT column_name(s)
FROM table1
RIGHT OUTER JOIN table2
ON table1.column_name=table2.column_name;
注释:在某些数据库中,RIGHT JOIN 称为 RIGHT OUTER JOIN


MariaDB [my_db]> select websites.name, access_log.count, access_log.date from access_log right join websites on access_log.site_id=websites.id  order by access_log.count desc;
+---------------+-------+------------+
| name          | count | date       |
+---------------+-------+------------+
| Facebook      |   545 | 2016-05-16 |
| Google        |   230 | 2016-05-14 |
| 菜鸟教程      |   220 | 2016-05-15 |
| Facebook      |   205 | 2016-05-14 |
| 菜鸟教程      |   201 | 2016-05-17 |
| 菜鸟教程      |   100 | 2016-05-13 |
| Google        |    45 | 2016-05-10 |
| 微博          |    13 | 2016-05-15 |
| 淘宝          |    10 | 2016-05-14 |
| stackoverflow |  NULL | NULL       |
+---------------+-------+------------+


-----------------------------------------------
SQL FULL OUTER JOIN 关键字
FULL OUTER JOIN 关键字只要左表(table1)和右表(table2)其中一个表中存在匹配,则返回行.
FULL OUTER JOIN 关键字结合了 LEFT JOIN 和 RIGHT JOIN 的结果。
SQL FULL OUTER JOIN 语法
SELECT column_name(s)
FROM table1
FULL OUTER JOIN table2
ON table1.column_name=table2.column_name;


mysql不支持完全外连接,可通过左外连接和右外连接及union实现
MariaDB [my_db]> select websites.id from websites left join access_log on websites.id=access_log.site_id union select websites.id from websites right join access_log on websites.id=access_log.site_id;



SQL UNION 操作符
UNION 操作符用于合并两个或多个 SELECT 语句的结果集。
请注意,UNION 内部的每个 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每个 SELECT 语句中的列的顺序必须相同。

SQL UNION 语法
SELECT column_name(s) FROM table1
UNION
SELECT column_name(s) FROM table2;
注释:默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。

SQL UNION ALL 语法
SELECT column_name(s) FROM table1
UNION ALL
SELECT column_name(s) FROM table2;
注释:UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。


SQL UNION 实例
下面的 SQL 语句从 "Websites" 和 "apps" 表中选取所有不同的country(只有不同的值):
SELECT country FROM Websites
UNION
SELECT country FROM apps
ORDER BY country;

SQL UNION ALL 实例
下面的 SQL 语句使用 UNION ALL 从 "Websites" 和 "apps" 表中选取所有的country(也有重复的值):
SELECT country FROM Websites
UNION ALL
SELECT country FROM apps
ORDER BY country;

带有 WHERE 的 SQL UNION ALL
下面的 SQL 语句使用 UNION ALL 从 "Websites" 和 "apps" 表中选取所有的中国(CN)的数据(也有重复的值):
SELECT country, name FROM Websites
WHERE country='CN'
UNION ALL
SELECT country, app_name FROM apps
WHERE country='CN'
ORDER BY country;



SQL SELECT INTO 语句
SELECT INTO 语句从一个表复制数据,然后把数据插入到另一个新表中。
MySQL 数据库不支持 SELECT ... INTO 语句,但支持 INSERT INTO ... SELECT 。
当然你可以使用以下语句来拷贝表结构及数据:
CREATE TABLE 新表
AS
SELECT * FROM 旧表 


SELECT * INTO newtable [IN externaldb] FROM table1;

或者只复制希望的列插入到新表中:
SELECT column_name(s) INTO newtable [IN externaldb] FROM table1;


SQL SELECT INTO 实例

创建 Websites 的备份复件:
SELECT *
INTO WebsitesBackup2016
FROM Websites;

只复制一些列插入到新表中:
SELECT name, url
INTO WebsitesBackup2016
FROM Websites;

只复制中国的网站插入到新表中:
SELECT *
INTO WebsitesBackup2016
FROM Websites
WHERE country='CN';

复制多个表中的数据插入到新表中:
SELECT Websites.name, access_log.count, access_log.date
INTO WebsitesBackup2016
FROM Websites
LEFT JOIN access_log
ON Websites.id=access_log.site_id;

提示:SELECT INTO 语句可用于通过另一种模式创建一个新的空表。只需要添加促使查询没有数据返回的 WHERE 子句即可:
SELECT *
INTO newtable
FROM table1
WHERE 1=0;


SQL INSERT INTO SELECT 语句
INSERT INTO SELECT 语句从一个表复制数据,然后把数据插入到一个已存在的表中。目标表中任何已存在的行都不会受影响。
SQL INSERT INTO SELECT 语法
我们可以从一个表中复制所有的列插入到另一个已存在的表中:

INSERT INTO table2
SELECT * FROM table1;

或者我们可以只复制希望的列插入到另一个已存在的表中:
INSERT INTO table2
(column_name(s))
SELECT column_name(s)
FROM table1;

MariaDB [my_db]> insert into websites (name,country) select app_name,country from apps;
MariaDB [my_db]> insert into websites (name,country) select app_name,country from apps where id=1;


SQL CREATE DATABASE 语句
CREATE DATABASE 语句用于创建数据库。
SQL CREATE DATABASE 语法
CREATE DATABASE dbname;

SQL CREATE DATABASE 实例
下面的 SQL 语句创建一个名为 "my_db" 的数据库:
CREATE DATABASE my_db;

********************************************
数据库表可以通过 CREATE TABLE 语句来添加。

SQL CREATE TABLE 语法
CREATE TABLE table_name
(
column_name1 data_type(size),
column_name2 data_type(size),
column_name3 data_type(size),
....
);
column_name 参数规定表中列的名称。
data_type 参数规定列的数据类型(例如 varchar、integer、decimal、date 等等)。
size 参数规定表中列的最大长度。

SQL CREATE TABLE 实例
现在我们想要创建一个名为 "Persons" 的表,包含五列:PersonID、LastName、FirstName、Address 和 City。
我们使用下面的 CREATE TABLE 语句

MariaDB [my_db]> create table persons1 (personID int,lastName varchar(255),firstName varchar(255),address varchar(255),city varchar(255));

MariaDB [my_db]> desc persons;
+-----------+--------------+------+-----+---------+-------+
| Field     | Type         | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+-------+
| PersonID  | int(11)      | YES  |     | NULL    |       |
| LastName  | varchar(255) | YES  |     | NULL    |       |
| FirstName | varchar(255) | YES  |     | NULL    |       |
| Address   | varchar(255) | YES  |     | NULL    |       |
| City      | varchar(255) | YES  |     | NULL    |       |
+-----------+--------------+------+-----+---------+-------+

 




SQL 约束(Constraints)
SQL 约束用于规定表中的数据规则。
如果存在违反约束的数据行为,行为会被约束终止。
约束可以在创建表时规定(通过 CREATE TABLE 语句),或者在表创建之后规定(通过 ALTER TABLE 语句)。
SQL 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,
....
);


在 SQL 中,我们有如下约束:
NOT NULL - 指示某列不能存储 NULL 值。
UNIQUE - 保证某列的每行必须有唯一的值。
PRIMARY KEY - NOT NULL 和 UNIQUE 的结合。确保某列(或两个列多个列的结合)有唯一标识,有助于更容易更快速地找到表中的一个特定的记录。
FOREIGN KEY - 保证一个表中的数据匹配另一个表中的值的参照完整性。
CHECK - 保证列中的值符合指定的条件。
DEFAULT - 规定没有给列赋值时的默认值。
在下面的章节,我们会详细讲解每一种约束。

MariaDB [my_db]> create table Persons(id_p int not null,lastName varchar(255) not null,firstName varchar(255),address varchar(255),city varchar(255),primary key(id_p));
MariaDB [my_db]> drop table Persons;

MariaDB [my_db]> create table Persons(id_p int not null primary key,lastName varchar(255) not null,firstName varchar(255),address varchar(255),city varchar(255));

删除表的字段的 not null 约束:
alter table x modify column_name null;
alter table x modify column_name not null;
----------------------
SQL UNIQUE 约束
UNIQUE 约束唯一标识数据库表中的每条记录。
UNIQUE 和 PRIMARY KEY 约束均为列或列集合提供了唯一性的保证。
PRIMARY KEY 约束拥有自动定义的 UNIQUE 约束。
请注意,每个表可以有多个 UNIQUE 约束,但是每个表只能有一个 PRIMARY KEY 约束。

MariaDB [my_db]> create table Persons(id_p int not null unique,lastName varchar(255) not null,firstName varchar(255),address varchar(255),city varchar(255));

MariaDB [my_db]> create table Persons(id_p int not null,lastName varchar(255) not null,firstName varchar(255),address varchar(255),city varchar(255),unique (id_p));

MariaDB [my_db]> CREATE TABLE Persons ( P_Id int NOT NULL, LastName varchar(255) NOT NULL, FirstName varchar(255), Address varchar(255), City varchar(255), CONSTRAINT uc_PersonID UNIQUE (P_Id,LastName) );

ALTER TABLE 时的 SQL UNIQUE 约束
当表已被创建时,如需在 "P_Id" 列创建 UNIQUE 约束,请使用下面的 SQL:
MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Persons ADD UNIQUE (P_Id)

如需命名 UNIQUE 约束,并定义多个列的 UNIQUE 约束,请使用下面的 SQL 语法:
MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Persons ADD CONSTRAINT uc_PersonID UNIQUE (P_Id,LastName)
alter table tb3 add constraint pk_id primary key (tb3_id);

ALTER TABLE 时的 SQL PRIMARY KEY 约束
当表已被创建时,如需在 "P_Id" 列创建 PRIMARY KEY 约束,请使用下面的 SQL:
MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Persons
ADD PRIMARY KEY (P_Id)

如需命名 PRIMARY KEY 约束,并定义多个列的 PRIMARY KEY 约束,请使用下面的 SQL 语法:
MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Persons
ADD CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)
注释:如果您使用 ALTER TABLE 语句添加主键,必须把主键列声明为不包含 NULL 值(在表首次创建时)。

撤销 UNIQUE 约束
如需撤销 UNIQUE 约束,请使用下面的 SQL:
MySQL:
ALTER TABLE Persons DROP INDEX uc_PersonID
SQL Server / Oracle / MS Access:
ALTER TABLE Persons DROP CONSTRAINT uc_PersonID

撤销 PRIMARY KEY 约束
如需撤销 PRIMARY KEY 约束,请使用下面的 SQL:
MySQL:
撤销PRIMARY KEY约束时,不论约束条件为一列还是多列,对于MySQL,撤销都是
ALTER TABLE Persons DROP PRIMARY KEY
由于PRIMARY KEY唯一性,MYSQL处理办法简单

SQL Server / Oracle / MS Access:
ALTER TABLE Persons DROP CONSTRAINT pk_PersonID

-----------------------------------
SQL PRIMARY KEY 约束
PRIMARY KEY 约束唯一标识数据库表中的每条记录。
主键必须包含唯一的值。
主键列不能包含 NULL 值。
每个表都应该有一个主键,并且每个表只能有一个主键

MySQL:
create table Persons(p_id int not null,lastName varchar(255) not null,firstName varchar(255),address varchar(255),city varchar(255),primary key(p_id));
或者
MariaDB [my_db]> CREATE TABLE Persons ( P_Id int NOT NULL, LastName varchar(255) NOT NULL, FirstName varchar(255), Address varchar(255), City varchar(255), PRIMARY KEY (P_Id) );
或者
MariaDB [my_db]> CREATE TABLE Persons ( P_Id int NOT NULL, LastName varchar ( 255 ) NOT NULL, FirstName varchar ( 255 ), Address varchar ( 255 ), City varchar ( 255 ), PRIMARY KEY ( P_Id ) );

SQL Server / Oracle / MS Access:
CREATE TABLE Persons(P_Id int NOT NULL PRIMARY KEY,LastName varchar(255) NOT NULL,FirstName varchar(255),Address varchar(255),City varchar(255));

需命名 PRIMARY KEY 约束,并定义多个列的 PRIMARY KEY 约束,请使用下面的 SQL 语法:
MySQL / SQL Server / Oracle / MS Access:
CREATE TABLE Persons
(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)
)
注释:在上面的实例中,只有一个主键 PRIMARY KEY(pk_PersonID)。然而,pk_PersonID 的值是由两个列(P_Id 和 LastName)组成的。

-------------------------
SQL FOREIGN KEY 约束
一个表中的 FOREIGN KEY 指向另一个表中的 UNIQUE KEY(唯一约束的键)。
让我们通过一个实例来解释外键。请看下面两个表:
"Persons" 表:
P_Id    LastName    FirstName    Address            City
1        Hansen        Ola            Timoteivn 10    Sandnes
2        Svendson    Tove        Borgvn 23        Sandnes
3        Pettersen    Kari        Storgt 20        Stavanger
"Orders" 表:
O_Id    OrderNo    P_Id
1        77895    3
2        44678    3
3        22456    2
4        24562    1
请注意,"Orders" 表中的 "P_Id" 列指向 "Persons" 表中的 "P_Id" 列。
"Persons" 表中的 "P_Id" 列是 "Persons" 表中的 PRIMARY KEY。
"Orders" 表中的 "P_Id" 列是 "Orders" 表中的 FOREIGN KEY。
FOREIGN KEY 约束用于预防破坏表之间连接的行为。
FOREIGN KEY 约束也能防止非法数据插入外键列,因为它必须是它指向的那个表中的值之一。

CREATE TABLE 时的 SQL FOREIGN KEY 约束
下面的 SQL 在 "Orders" 表创建时在 "P_Id" 列上创建 FOREIGN KEY 约束:
MySQL:
CREATE TABLE Orders
(
O_Id int NOT NULL,
OrderNo int NOT NULL,
P_Id int,
PRIMARY KEY (O_Id),
FOREIGN KEY (P_Id) REFERENCES Persons(P_Id)
);

SQL Server / Oracle / MS Access:
CREATE TABLE Orders
(
O_Id int NOT NULL PRIMARY KEY,
OrderNo int NOT NULL,
P_Id int FOREIGN KEY REFERENCES Persons(P_Id)
);

如需命名 FOREIGN KEY 约束,并定义多个列的 FOREIGN KEY 约束,请使用下面的 SQL 语法:
MySQL / SQL Server / Oracle / MS Access:
CREATE TABLE Orders
(
O_Id int NOT NULL,
OrderNo int NOT NULL,
P_Id int,
PRIMARY KEY (O_Id),
CONSTRAINT fk_PerOrders FOREIGN KEY (P_Id)
REFERENCES Persons(P_Id)
);

ALTER TABLE 时的 SQL FOREIGN KEY 约束
当 "Orders" 表已被创建时,如需在 "P_Id" 列创建 FOREIGN KEY 约束,请使用下面的 SQL:
MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Orders
ADD FOREIGN KEY (P_Id)
REFERENCES Persons(P_Id)
如需命名 FOREIGN KEY 约束,并定义多个列的 FOREIGN KEY 约束,请使用下面的 SQL 语法:
MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Orders
ADD CONSTRAINT fk_PerOrders
FOREIGN KEY (P_Id)
REFERENCES Persons(P_Id)

撤销 FOREIGN KEY 约束
如需撤销 FOREIGN KEY 约束,请使用下面的 SQL:
MySQL:
ALTER TABLE Orders
DROP FOREIGN KEY fk_PerOrders
SQL Server / Oracle / MS Access:
ALTER TABLE Orders
DROP CONSTRAINT fk_PerOrders

使用工具plsql来新增外键约束
注意,在创建外键约束时,必须先创建外键约束所依赖的表,并且该列为该表的主键

建外键约束的方式
在创建表的时候指定外键约束
CREATE TABLE 表名
    (
        column1 datatype null/not null,
        column2 datatype null/not null,
        ...
        CONSTRAINT 外键约束名 FOREIGN KEY  (column1,column2,... column_n) 
        REFERENCES 外键依赖的表 (column1,column2,...column_n)
        ON DELETE CASCADE--级联删除
    );
在创建表后增加外键约束
ALTER TABLE 表名
    ADD CONSTRAINT 外键约束名
    FOREIGN KEY (column1, column2,...column_n) 
    REFERENCES 外键所依赖的表 (column1,column2,...column_n)
    ON DELETE CASCADE;--级联删除
使用工具plsql来新增外键约束
注意,在创建外键约束时,必须先创建外键约束所依赖的表,并且该列为该表的主键

Oracle数据库中,对指定外键的表进行增删改的情况:
子表:谁创建外键谁就是子表
父表:这个外键所依赖的表
create table father(
f_no number(2));--插入数据1 2 3 4
create table son(
s_no number(2),
f_no number(2))--插入两列1 2 3 4
--删除父表数据
delete from father where f_no=1 --报错违反约束
--删除父表
drop table father  --报错违反约束
--更新父表数据
--禁用约束可以更新ALTER TABLE son disable constraint f_f; 
update father set f_no =7 where f_no=1--报错违反约束
--对父表插入数据
insert into father values(6)--可以插入
--删除子表数据
delete from son where s_on=1--可以删除
--删除子表
drop table son--可以删除
--更新子表数据
update son set s_no=6 where s_no=1 --可以更新
update son set f_no=6 where s_no=6  --可以更新
--对子表插入数据 
insert into son values(7,7)--父表没有7,违反约束
insert into son values(1,1)--父表有1可以插入    
insert into son values(8,1)--父表有1可以插入
总结:
一、删除时,未指定cascade时
  1)删除父表/数据
      a.因为子表与父表一一对应,删除父表数据时,需要先把子表对应数据删除否则无法删除
     b. 同理,删除表的时候,也需要先删除子表再删除父表
解决方案:
     a.指定cascade,删除父表、数据
        CASCADE指当删除主表中被引用列的数据时,级联删除子表中相应的数据行。
     b.禁用约束(子表的外键约束)
         ALTER TABLE 表名 disable constraint 约束名;
 2)删除子表:可以删除子表或者数据不报错
二、更新时
        a.更新父表会违反约束
        b.可以更新子表
        c.没有针对约束的级联更新
三、插入时
         a.父表可以插入
         b.子表插入会违反约束 
----------------------------------------------------------
CHECK 约束用于限制列中的值的范围。
如果对单个列定义 CHECK 约束,那么该列只允许特定的值。
如果对一个表定义 CHECK 约束,那么此约束会基于行中其他列的值在特定的列中对值进行限制。

CREATE TABLE 时的 SQL CHECK 约束
下面的 SQL 在 "Persons" 表创建时在 "P_Id" 列上创建 CHECK 约束。CHECK 约束规定 "P_Id" 列必须只包含大于 0 的整数。
MySQL:
CREATE TABLE Persons
(
P_Id int NOT NULL [CHECK (P_Id>0)],
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
CHECK (P_Id>0)
)

如需命名 CHECK 约束,并定义多个列的 CHECK 约束,请使用下面的 SQL 语法:
MySQL / SQL Server / Oracle / MS Access:
CREATE TABLE Persons
(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
CONSTRAINT chk_Person CHECK (P_Id>0 AND City='Sandnes')
)

ALTER TABLE 时的 SQL CHECK 约束
当表已被创建时,如需在 "P_Id" 列创建 CHECK 约束,请使用下面的 SQL:
MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Persons ADD CHECK (P_Id>0)
如需命名 CHECK 约束,并定义多个列的 CHECK 约束,请使用下面的 SQL 语法:
ALTER TABLE Persons ADD CONSTRAINT chk_Person CHECK (P_Id>0 AND City='Sandnes')


撤销 CHECK 约束
如需撤销 CHECK 约束,请使用下面的 SQL:
SQL Server / Oracle / MS Access:
ALTER TABLE Persons DROP CONSTRAINT chk_Person
MySQL:
ALTER TABLE Persons DROP CHECK chk_Person


---------------------------------------------

SQL DEFAULT 约束
DEFAULT 约束用于向列中插入默认值。
如果没有规定其他的值,那么会将默认值添加到所有的新记录。

CREATE TABLE 时的 SQL DEFAULT 约束
下面的 SQL 在 "Persons" 表创建时在 "City" 列上创建 DEFAULT 约束:
My SQL / SQL Server / Oracle / MS Access:
CREATE TABLE Persons
(
    P_Id int NOT NULL,
    LastName varchar(255) NOT NULL,
    FirstName varchar(255),
    Address varchar(255),
    City varchar(255) DEFAULT 'Sandnes'
)
通过使用类似 GETDATE() 这样的函数,DEFAULT 约束也可以用于插入系统值:
CREATE TABLE Orders
(
    O_Id int NOT NULL,
    OrderNo int NOT NULL,
    P_Id int,
    OrderDate date DEFAULT GETDATE()
)


ALTER TABLE 时的 SQL DEFAULT 约束
当表已被创建时,如需在 "City" 列创建 DEFAULT 约束,请使用下面的 SQL:
MySQL:
ALTER TABLE Persons
ALTER City SET DEFAULT 'SANDNES'
SQL Server / MS Access:
ALTER TABLE Persons
ADD CONSTRAINT ab_c DEFAULT 'SANDNES' for City

Oracle:
ALTER TABLE Persons
MODIFY City DEFAULT 'SANDNES'
撤销 DEFAULT 约束
如需撤销 DEFAULT 约束,请使用下面的 SQL:

MySQL:
ALTER TABLE Persons
ALTER City DROP DEFAULT

SQL Server / Oracle / MS Access:
ALTER TABLE Persons
ALTER COLUMN City DROP DEFAULT



SQL CREATE INDEX 语句
CREATE INDEX 语句用于在表中创建索引。
在不读取整个表的情况下,索引使数据库应用程序可以更快地查找数据。
索引
您可以在表中创建索引,以便更加快速高效地查询数据。
用户无法看到索引,它们只能被用来加速搜索/查询。
注释:更新一个包含索引的表需要比更新一个没有索引的表花费更多的时间,这是由于索引本身也需要更新。因此,理想的做法是仅仅在常常被搜索的列(以及表)上面创建索引。


SQL CREATE INDEX 语法
在表上创建一个简单的索引。允许使用重复的值:
CREATE INDEX index_name
ON table_name (column_name)

SQL CREATE UNIQUE INDEX 语法
在表上创建一个唯一的索引。不允许使用重复的值:唯一的索引意味着两个行不能拥有相同的索引值。Creates a unique index on a table. Duplicate values are not allowed:
CREATE UNIQUE INDEX index_name
ON table_name (column_name)
注释:用于创建索引的语法在不同的数据库中不一样。因此,检查您的数据库中创建索引的语法

CREATE INDEX 实例
下面的 SQL 语句在 "Persons" 表的 "LastName" 列上创建一个名为 "PIndex" 的索引:
CREATE INDEX PIndex
ON Persons (LastName)
如果您希望索引不止一个列,您可以在括号中列出这些列的名称,用逗号隔开:
CREATE INDEX PIndex
ON Persons (LastName, FirstName)


 


SQL 撤销索引、撤销表以及撤销数据库
通过使用 DROP 语句,可以轻松地删除索引、表和数据库。

DROP INDEX 语句
DROP INDEX 语句用于删除表中的索引。

用于 MS Access 的 DROP INDEX 语法:
DROP INDEX index_name ON table_name

用于 MS SQL Server 的 DROP INDEX 语法:
DROP INDEX table_name.index_name

用于 DB2/Oracle 的 DROP INDEX 语法:
DROP INDEX index_name

用于 MySQL 的 DROP INDEX 语法:
ALTER TABLE table_name DROP INDEX index_name

DROP TABLE 语句
DROP TABLE 语句用于删除表。
DROP TABLE table_name

DROP DATABASE 语句
DROP DATABASE 语句用于删除数据库。
DROP DATABASE database_name

TRUNCATE TABLE 语句
如果我们仅仅需要删除表内的数据,但并不删除表本身,那么我们该如何做呢?
请使用 TRUNCATE TABLE 语句:
TRUNCATE TABLE table_name



SQL NULL 值
如果表中的某个列是可选的,那么我们可以在不向该列添加值的情况下插入新记录或更新已有的记录。这意味着该字段将以 NULL 值保存。
NULL 值的处理方式与其他值不同。
NULL 用作未知的或不适用的值的占位符。
Note注释:无法比较 NULL 和 0;它们是不等价的

SELECT LastName,FirstName,Address FROM Persons
WHERE Address IS NOT NULL

SQL NULL 函数

我们使用下面的 SELECT 语句:
SELECT ProductName,UnitPrice*(UnitsInStock+UnitsOnOrder) FROM Products
在上面的实例中,如果有 "UnitsOnOrder" 值是 NULL,那么结果是 NULL。

微软的 ISNULL() 函数用于规定如何处理 NULL 值。
NVL()、IFNULL() 和 COALESCE() 函数也可以达到相同的结果。
在这里,我们希望 NULL 值为 0。
下面,如果 "UnitsOnOrder" 是 NULL,则不会影响计算,因为如果值是 NULL 则 ISNULL() 返回 0:
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
MySQL
MySQL 也拥有类似 ISNULL() 的函数。不过它的工作方式与微软的 ISNULL() 函数有点不同。
在 MySQL 中,我们可以使用 IFNULL() 函数,如下所示:
SELECT ProductName,UnitPrice*(UnitsInStock+IFNULL(UnitsOnOrder,0))
FROM Products
或者我们可以使用 COALESCE() 函数,如下所示:
SELECT ProductName,UnitPrice*(UnitsInStock+COALESCE(UnitsOnOrder,0))
FROM Products

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值