MySQL_2_制約とマルチテーブルのクエリ

MySQLデータベース

第四章データ整合性

役割:データベースへのユーザ入力データの保存を確実に正しいです。

=あなたがテーブルを作成するときにテーブルに追加されたデータ整合性制約を確認してください。

分類の整合性:

  • エンティティ整合性。
  • ドメインの整合性、
  • 参照整合性;

4.1エンティティの整合性

エンティティ:実体(エンティティ)に代わってテーブル内の行(レコード)。

アクションのエンティティの完全性:データの各行を識別するは繰り返しません。

制約のタイプ:

主キー制約(主キー)

唯一の制約(ユニーク)

自動成長列(AUTO_INCREMENT)

4.1.1主キー制約(主キー)

注意:各テーブルには主キーを持っている必要があります

特徴:データのみとnullにすることはできません

例:

追加する最初の方法:

CREATE TABLE studdent(
    id int primary key,
    name varchar(50)
);

追加する2番目の方法:この方法での利点は、あなたが主キーを作成することができるということです

CREATE TABLE student(
    id int,
    name varchar(50),
    primary key(id)
);
CREATE TABLE student(
    classid int,
    stuid int,
    name varchar(50),
    primary key(classid,stuid)
);

最初のテーブルを作成し、主キーを追加します。第三の方法を追加します。

CREATE TABLE studdent(
    id int;
    name varchar(50)
);
ALTER TABLE student ADD PRIMARY KEY(id);
唯一の制約(ユニーク)4.1.2

特徴:データを繰り返すことはできませんが、nullにすることができ

CREATE TABLE student(
    id int primary key,
    name varchar(50) unique
);
4.1.3自動成長列(AUTO_INCREMENT)

SQLServerデータベース(アイデンティティ)は、Oracle Database(シーケンス)

成長は自動的に主キー値に加え、唯一の整数列型とすることができます

CREATE TABLE student(
    id int primary key auto_increment,
    name varchar(50)
);

INSERT INTO student(name) values('tom');

初期値の自動増加を変更します。

ALTER TABLE tbl_name AUTO_INCREMENT = n;

4.2ドメインの整合性

ドメインの整合性作用:このセルのデータを制限するには、そのようなものがないので、列中の他の細胞と比較し、正しいです

ドメインは、現在のセルを表し、

ドメイン整合性制約:非空制約(nullでない)制約デフォルト値のデータ型(デフォルト)

制約をチェックする(MySQLがサポートしていません)チェック(性別=「男性」または性別=「女性」)

4.2.1データ型

数値型

タイプ サイズ レンジ(署名) レンジ(符号なし) 使用
TINYINT 1つのバイト (-128127) (0255) 小さな整数値
SMALLINT 2つのバイト (-32768,32767) (0から65535) 大きな整数値
MEDIUMINT 3つのバイト (-8388608,8388607) (0,16777215) 大きな整数値
INTまたはINTEGER 4つのバイト (-2147483648,2147483647) (0,4294967295) 大きな整数値
BIGINT 8つのバイト (-9233372036854775808,9233372036854775807) (0,18446744073709551615) 最大の整数値
浮く 4つのバイト 単精度浮動小数点値
ダブル 8つのバイト 倍精度浮動小数点値
DOUBLE(M、D) 8バイト、Mは長さ、Dは小数点以下の桁数を表します。 同上。、バウンドMとD 同上。、バウンドMとD 倍精度浮動小数点数
DECIMAL(M、D) DECIMAL(M、D)、M> D、M + 2は、そうでなければD + 2である場合 そしてDは、Mの値に依存しているMは、65の最大値であります そしてDは、Mの値に依存しているMは、65の最大値であります 小さな値

日付タイプ:

これは、日付と時刻のタイプは、時間値DATETIME、DATE、TIMESTAMP、TIME、およびYEARであることを示します。

指定された違法のMySQLの値が表現できない場合の各タイプは、時間有効範囲と「ゼロ」の「ゼロ」値の値を有します。

タイプ サイズ(バイト) スコープ フォーマット 使用
日付 3 1000年1月1日/ 9999-12-31 YYYY-MM-DD 日付値
時間 3 '-838:59:59' / '838:59:59' HH:MM; SS Time値または期間
1 1901/2155 YYYY 年の値
日付時刻 8 1000年1月1日00:00:00 / 9999-12-31 23時五十九分59秒 YYYY-MM-DD HH:MM:SS 日付と時刻の値の混合
TIMESTAMP 4 1970-01-0100:00:00/2038終了時間は2,147,483,647秒、北京2038年1月19日11時14分07秒GMT、2038年1月19日早朝3時14分07秒です YYYYMMDDHHMMSS 日付と時刻の値、タイムスタンプをミキシング

文字列型:

タイプ サイズ 使用
CHAR 0〜255の文字 固定長文字列
VARCHAR 0から65536のバイト 可変長文字列
TINYBLOB 0〜255のバイト バイナリ文字列ではありません以上255文字以下
TINYTEXT 0〜255のバイト 短いテキスト文字列
BLOB 0から65536のバイト バイナリ形式で長いテキストデータ
テキスト 0から65536のバイト 長いテキストデータ
MEDIUMBLOB 0-16777215バイト 中位の長さの形でバイナリテキストデータ
MEDIUMTEXT 0-16777215バイト ミディアムの長さのテキストデータ
LONGBLOB 0-4294967295バイト バイナリ形式のグレートテキストデータ
LONGTEXT 0-4294967295バイト グレートテキストデータ

CHAR和VARCHAR类型类似,但它们保存和检索的方式不同。它们的最大长度和是否尾部空格被保留等方面也不同。在存储或检索过程中不进行大小写转换。

BINARY和VARBINARY类类似于CHAR和VARCHAR,不同的是它们包含二进制字符串而不要非二进制字符串。也就是说,它们包含字节字符串而不是字符字符串。这说明它们没有字符集,并且排序和比较基于列值字节的数值值。

BLOB是一个二进制大对象,可以容纳可变数量的数据。有4种BLOB类型: TINYBLOB、 BLOB、MEDIUMBLOB和LONGBLOB。它们只是可容纳值的最大长度不同。

有4种TEXT类型: TINYTEXT、 TEXT、MEDIUMTEXT和LONGTEXT。 这些对应4种BLOB类型,有相同的最大长度和存储需求。

4.2.2 非空约束

not null

CREATE TABLE student(
    id int primary key,
    name varchar(50) not null,
    sex varchar(10)
);

INSERT INTO student values(1,'tom',null);
4.2.3 默认值约束

default

CREATE TABLE student(
    id int primary key,
    name varchar(50) not null,
    sex varchar(10) default '男'
);

INSERT INTO student values(1,'marry','女');
INSERT INTO student values(2,'tom',default);
INSERT INTO student(id,name) values(1,'jack');

4.3 引用完整性

(参照完整性)

外键约束:FOREIGN KEY

示例:

#学生表
CREATE TABLE student(
    sid int primary key,
    name varchar(50) not null,
    sex varchar(10) default '男'
);
#成绩表
CREATE TABLE score(
    id int primary key,
    score int,
    sid int,
    CONSTRAINT fk_score_sid FOREIGN KEY(sid) REFERENCES student(sid)
);

#第二种写法(简写)
CREATE TABLE score(
    id int primary key,
    score int,
    sid int references student(sid),
);
-- 外键列的数据类型一定要与主键的类型一致

第二种添加外键方式。

#成绩表
CREATE TABLE score(
    id int primary key,
    score int,
    sid int,
);

ALTER TABLE score ADD  CONSTRAINT fk_score_sid FOREIGN KEY(sid) REFERENCES student(sid);

第五章 多表查询

多个表之间是有关系的,那么关系靠谁来维护?

多表约束:外键约束。

5.1 多表的关系

5.1.1 一对多关系

客户和订单,分类和商品,部门和员工。

一对多建表原则:在多的一方创建一个字段,字段作为外键指向一的一方的主键。

5.1.2 多对多关系

学生和课程:

多对多关系建表原则:需要创建第三张表,中间表至少两个字段,这两个字段分别作为外键指向各自一方的主键。

5.1.3 一对一关系

在实际开发中应用不多,因为一对一可以创建成一张表。

两种建表原则:

唯一外键对应:假设一对一是一个一对多的关系,在多的一方创建一个外键指向一的一方的主键,将外键设置为unique和 not null。

主键对应:让一对一的双方的主键进行建立关系。

5.2 多表查询

多表查询有如下几种:

  1. 合并结果集:UNION、UNION ALL

  2. 连接查询

    2.1内连接[INNER] JOIN ON

    2.2外连接OUTER JOIN ON

    • 左外连接LEFT [OUTER] JOIN
    • 右外连接RIGHT [OUTER] JOIN
    • 全外连接(MySQL不支持)FULL Join

    2.3自然连接NATURAL JOIN

  3. 子查询

5.2.1 合并结果集

作用:合并结果集就是把两个select语句的查询结果合并到一起。

合并结果集有两种方式:

UNION:去除重复记录,例如

SELECT * FROM t1 UNION SELECT * FROM t2;

UNION ALL:不去除重复记录,例如:

SELECT * FROM t1 UNION ALL SELECT * FROM t2;

注意:被合并的两个结果:列数、列类型必须相同。

5.2.2 连接查询

连接查询就是求出多个表的乘积,例如t1连接t2,那么查询的结果就是t1*t2。

连接查询会产生笛卡尔积,假设集合A={a,b},集合B={0,1,2},则两个集合的笛卡尔积为{(a,0),(a,1),(a,2),(b,0),(b,1),(b,2)}。可以扩展到多个集合的情况。

那么多表查询产生这样的结果并不是我们想要的,那么怎么去除重复的,不想要的记录呢,当然是通过条件过滤。通常要查询的多个表之间都存在关联系,那么就通过关联关系去除笛卡尔积。

示例1:现有两张表

emp表:

CREATE TABLE emp(
    empno int,
    ename varchar(50),
    job varchar(50),
    mgr int,
    hiredate date,
    sal decimal(7,2),
    deptno int
);

dept表:

CREATE TABLE dept(
    deptno int,
    dname varchar(14),
    loc varchar(13)
);

执行如下语句:

SELECT * FROM emp,dept;

使用主外键关系作为条件来去除无用信息

SELECT * FROM emp,dept WHERE emp.deptno = dept.deptno;

上面查询会把两张表的所有列都查询出来,也许你不需要那么多列,这是就可以指定要查询的列了。

SELECT emp.ename,emp.sal,emp.comn,emp.deptno,emp.dname
FROM emp,dept
WHERE emp.deptno = dept.deptno;

一、内连接

上面的连接语句就是内连接,但它不是SQL标准中的查询方式。

SQL标准的内连接为:

SELECT *
FROM emp e
INNER JOIN dept d
ON e.deptno = d.deptno;

内连接的特点:查询结果必须满足条件。

二、外连接

包括左外连接和右外连接,外连接的特点:查询出的结果存在不满足条件的可能。

a、左外连接

SELECT * FROM emp e
LEFT OUTER JOIN dept d
ON  e.deptno = d.deptno;

左连接是先查询出左表(即以左表为主),然后查询右表,右表中满足条件的显示出来,不满足条件的显示NULL。

我们还是用上面的例子来说明。其中emp表中"Bob"这条记录中,部门编号为50, 而dept表中不存在部门编号为50的记录,所以“张三”这条记录,不能满足e.deptno=d.deptno这条件。 但在左连接中,因为emp表是左表,所以左表中的记录都会查询出来,即“Bob"这条记录也会查出,但相应的右表部分显示NULL。

b、右外连接

右连接就是先把右表中所有记录都查询出来,然后左表满足条件的显示,不满足显示NULL。例如在dept表中的40部门并不存在员工,但在右连接中,如果dept表为右表,那么还是会查出40部门,但相应的员工信息为NULL。

SELECT * FROM emp e
RIGHT OUTER JOIN dept d
ON e.deptno = d.deptno;

连接查询心得:

连接不限于两张表,连接查询也可以是三张、四张,甚至N张表的连接查询。通常连接查询不可能需要整个笛卡尔积,而只是需要其中一部分,那么这时就需要使用条件来去除不需要的记录。这个条件大多数情况下都是使用主外键关系去除。

两张表的连接查询一定有一个主外键关系,三张表的连接查询就一定有两个 主外键关系,所以在大家不是很熟悉连接查询时,首先要学会去除无用笛卡尔积,那么就是用主外键关系作为条件来处理。如果两张表的查询,那么至少有一个主外键条件,三张表连接至少有两个主外键条件。

5.2.3 子查询

一个select语句中包含另一个完整的select语句。

子查询就是嵌套查询,即SELECT中包含SELECT,如果一条语句中存在两个或两个以上的SELECT,那么就是子查询语句了。里面的查询叫做子查询,外层的查询叫父查询,一般情况都是先执行子查询再执行父查询。

子查询出现的位置:

  1. where后,作为被查询的条件的一部分;
  2. from后,作表。

当子查询出现在where后作为条件时,还可以使用如下关键字:

  1. any
  2. all

子查询结果集的形式:

  1. 单行单列(用于条件)
  2. 单行多列(用于条件)
  3. 多行单列(用于条件)
  4. 多行多列(用于表)

示例:

1、查询工资高于JONES的员工

分析:

查询条件:工资>JONES,其中JONES工资需要一条子查询

第一步:查询JONES的工资

SELECT sal FROM emp WHERE ename = 'JONES';

第二步:查询高于JONES工资的员工

SELECT * FROM emp WHERE sal > (第一步的结果);

结果:

SELECT * FROM emp WHERE sal > (SELECT sal FROM emp WHERE ename = 'JONES');

2、查询与SCOTT同一个部门的员工

子查询作为条件

子查询形式为单行单列

分析:

查询条件:部门=SCOTT的部门编号,其中SCOTT的部门编号需要一条子查询

第一步:查询SCOTT的部门编号

SELECT deptno FROM emp WHERE ename = 'SCOTT';

第二步:查询部门编号等于SCOTT的部门编号的员工

SELECT * FROM emp WHERE deptno = (SELECT deptno FROM emp WHERE ename = 'SCOTT');

3、工资高于30号部门所有人的员工信息

分析:

SELECT * FROM emp WHERE sal >(SELECT MAX(sal) FROM emp WHERE deptno = 30);

查询条件:工资高于30部门所有人工资,其中30号部门所有人工资是子查询,高于所有需要使用ALL关键字。

第一步:查询30号部门所有人工资

SELECT sal FROM emp WHERE deptno = 30;

第二步:查询高于30号部门所有人工资的员工信息

SELECT * FROM emp WHERE sal > ALL(第一步结果);

结果:

SELECT * FROM emp WHERE sal > ALL(SELECT sal FROM emp WHERE deptno = 30);

4、工资高于30号部门中任意一个人的员工信息

SELECT * FROM emp WHERE sal > ANY(SELECT sal FROM emp WHERE deptno = 30);

子查询作为条件

子查询形式为多行单列(当子查询结果集形式为多行单列时可以使用ALL或ANY关键字)

5、查询1982年后入职员工中工资最高的员工信息

SELECT *,MAX(sal) FROM (SELECT * FROM emp WHERE hiredate >= '1982-01-01') AS temp;
5.2.4 导出导入数据库

1、使用命令方式

导出数据库表:

mysqldump -u用户名 -p 数据库名 > 导出路径与文件名

导入数据库表:

mysql -u用户名 -p
mysql>use 数据库名
然后使用source命令,后面参数为脚本文件(如这里用到的.sql)
mysql>source 导出路径与文件名

2、使用工具导入导出工具

5.2.5 创建用户和授权

创建用户

CREATE USER  用户名及地址(`zhangsan`@`localhost`) IDENTIFIED BY 密码('123456');

授权

GRANT ALL(权限) ON school.*(数据库名.表名) TO `zhangsan`(用户名)

撤销授权

REVOKE ALL(权限) ON school.*(数据库名.表名) TO `zhangsan`(用户名);

删除用户

DROP USER `zhangsan`(用户名);

おすすめ

転載: www.cnblogs.com/schhz208/p/11735778.html