规范化
约束
- NOT NULL
- UNIQUE
- PRIMARY KEY
- DEFAULT
FOREIGN KEY:引用父表的某个唯一值
引用完整性:插入外键列的值必须已经存在于父表的来源列中--创建外键create table interest(int_id varchar(50) NOT NULL,contact_id INT NOT NULL,FOREIGN KEY (contact_id)REFERENCES my_contacts(contact_id));
UNIQUE约束
--当表已被创建时,如需在 "Id_P" 列创建 UNIQUE 约束,请使用下列 SQL:ALTER TABLE PersonsADD UNIQUE (Id_P)--如需命名 UNIQUE 约束,并定义多个列的 UNIQUE 约束,请使用下面的 SQL 语法:ALTER TABLE PersonsADD CONSTRAINT uc_PersonID UNIQUE (Id_P,LastName)
CHECK约束
--如果在表已存在的情况下为 "Id_P" 列创建 CHECK 约束,请使用下面的 SQL:ALTER TABLE PersonsADD CHECK (Id_P>0)--如果需要命名 CHECK 约束,以及为多个列定义 CHECK 约束,请使用下面的 SQL 语法:ALTER TABLE PersonsADD CONSTRAINT chk_Person CHECK (Id_P>0 AND City='Sandnes')CREATE TABLE piggy_bank(id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,coin CHAR(1) CHECK (coin IN ('P','N','D','Q')))
原子性
具有原子性的列不会有多个类型相同的值
food_name ingredients bread flour,milk,egg,oil salad lettuce,tomato,cucumber
具有原子性数据的表中不会有多个存储同类数据的列
teacher student1 student2 Mr.Tang Joe Ron
第一范式 1NF
每个数据必须包含具有原子性的值
每个数据必须有独一无二的识别项,人称主键(Primary Key)
数据模式
一对一
父表中的一条记录只与子表中的一条记录相关联- 抽出数据写出更快的查询
- 某列包含未知的值,单独存储,以避免出现null
- 隔离数据,现在访问
- 大块数据,例如BLOB
一对多
父表中的一条记录与子表中的多条记录关联
但子表中的一条记录只与父表中的一条记录关联多对多
一张表的多行记录与另一张表的多行记录相关联
使用junction table(连接表)转化为两个一对多关系
依赖
T.x->T.y表示为在表T中,y列函数依赖于x列
部分函数依赖
非主键的列依赖于组主合键的某个部分(但不完全依赖于组合主键)传递函数依赖
任何非键列与另一个非键类有关联第二范式2NF
符合第一范式且没有部分函数依赖第三范式3NF
符合第二范式且没有传递函数依赖
联接查询
交叉联接(AKA 笛卡尔联接,叉积)
CROSS JOIN 返回两张表的每一行相乘的结果
SELECT b.boy,t.toyFROM boys as b CROSS JOIN toys as t--CROSS JOIN可以用逗号代替SELECT b.boy,t.toyFROM boys as b, toys as t
内联接
内联接就是通过查询中的条件移除了某些结果数据行后的交叉联接
相等联接
SELECT boys.boy ,toys.toyFROM boysINNER JOIN toysON boys.toy_id=toys.toy_id
不等联接
SELECT boys.boy ,toys.toyFROM boysINNER JOIN toysON boys.toy_id<>toys.toy_idORDER BY boys.boy
自然联接
利用相同列名的内联接SELECT boys.boy ,toys.toyFROM boysNATURAL JOIN toys
子查询
子查询一般只返回一个值,使用IN是列外情况
非关联子查询:如果子查询可以独立运行且不会引用外层查询的任何结果,即称为非关联子查询
关联子查询:内层查询的解析需要依赖外层查询的结果
SELECT mc.name ,mc.emailFROM my_contacts mcWHERE NOT EXISTS(SELECT * FROM job_current jcWHERE mc.contact_id = jc.contact_id);--mc在外层指定
外联接
左外联接
LEFT OUTER JOIN会匹配左表中的每一行及右表中符合条件的行
左外联接的结果集中的NULL表示右表中没有找到与左表相符的记录右外联接
与左外联接相反
自联接
- 自引用外键
用属于同一张表的其他列作为外键。
ID NAME BOSS_ID 1 TOM 1 2 JACK 1
BOSS_ID引用了ID字段
- 自联接
自联接把单一的表当成两张具有相同信息的表来进行查询SELECT c1.name,c2.name as BOSSFROM clown_info c1INNER JOIN clown_info c2ON c1.boss_id =c2.id
集合
联和(UNION)
将多张表的查询结果合并至一张表,默认无重复(相当于去并集?)SELECT title FROM job_currentUNIONSELECT title FROM job_desiredUNIONSELECT title FROM job_listings
限制
每个SELECT中列必须一致,统计函数与表达式也必须相同,类型相同或者可以转换
SELECT语句顺序不重要
默认无重复,需要重复可使用UNION ALL交集(INTERSECT)
SELECT title FROM job_currentINTERSECTSELECT title FROM job_desired
差集(EXCEPT)
SELECT title FROM job_currentEXCEPTSELECT title FROM job_desired
事务
ACID
原子性
事务里的每一个步骤都必须完成,否则只能都不完成。一致性
事务完成后应该维持数据库的一致性。隔离性
表示每次事务都会看到具有一致性的数据库,无论其他事务有什么行动。持久性
事务完成后,数据库需要正确存储数据并保护数据免受断电或其他威胁的伤害。
管理事务
START TRANSACTION--持续追踪后续所有SQL语句,直到输入COMMIT或ROLLBACK为止COMMIT--提交ROLLBACK--回滚
常用语句
SHOW CREATE TABLE tablename 显示创建表的SQL语句SHOW WARNINGS 显示错误信息SHOW INDEX FROM tablename 显示索引
ALTER TABLE tablenameADD COLUMN columnname varchar(10) AFTER colname新列的顺序除了AFTER还有 BEFORE,FIRST,SECOND可供选择
ALTER TABLE projekt_listCHANGE COLUMN num proj_id INT NOT NULL auto_increment,ADD PRIMARY KEY (proj_id)ALTER TABLE projekt_listMODIFY COLUMN num proj_id INT NOT NULL auto_incrementALTER TABLE projekt_listDROP COLUMN star_date--删除一列会删除该列的所有数据,在删除之前先选出列以确定那是你要删除的列
--一些字符串操作函数SELECT SUBSTRING(,)UPPER()LOWER()REVERSE()LTRIM()RTRIM()LENGTH()
UPDATE movie_tableSET category =CASE --根据条件更新,还可以搭配SELECT,INSERT,DELETWHEN comedy='T' THEN 'comedy'WHEN cartoon='T' AND rating='G' THEN 'family'ELSE 'misc'
SELECT first_name,SUM(sales) AS saleFROM cookie_salesGROUP BY first_nameORDER BY sale DESC--常用函数SUM() COUNT() MIN() MAX()--组合使用SELECT COUNT(DISTINCT sale_date)FROM cookie_salesDISTINCT--去重LIMIT--限制返回行数(限MySQL)
注意
null代表未定义,它不是0也不是空字符串,值可以是null但不会等于null,两个null也不能比较
注意和编程语言的不同// Equals applied to any null object returns false. bool b = (t.Equals(s)); Console.WriteLine(b); // Equality operator also returns false when one // operand is null. Console.WriteLine("Empty string {0} null string", s == t ? "equals": "does not equal"); // Returns true. Console.WriteLine("null == null is {0}", null == null);
不要在SQL中使用双引号
- 不要直接查找null而要使用IS NULL
- BETWEEN AND 可以替代<= AND >=,而且可以用于字符,但是较小的值必须放在前面
- 除了NOT IN,AND,OR之外,NOT必须接在WHERE之后
- 在删除和更新之前先查询