淘先锋技术网

首页 1 2 3 4 5 6 7

MySql:关系型(表格)数据库

主要术语

  • 冗余:存储两倍数据,冗余降低了性能,但提高了数据的安全性。
  • 主键:主键是唯一的。一个数据表中只能包含一个主键。你可以使用主键来查询数据。最好是完全业务无关的字段
  • 外键:外键用于关联两个表
  • 复合键:复合键(组合键)将多个列作为一个索引键,一般用于复合索引
  • 索引:使用索引可快速访问数据库表中的特定信息。索引是对数据库表中一列或多列的值进行排序的一种结构。类似于书籍的目录。
  • 参照完整性: 参照的完整性要求关系中不允许引用不存在的实体。与实体完整性是关系模型必须满足的完整性约束条件,目的是保证数据的一致性

连接

mysql -u root -p

创建database:CREATE

CREATE DATABASE 数据库名;

  • 存在则不创建;设定编码集utf-8
    CREATE DATABASE IF NOT EXISTS 数据库名 DEFAULT CHARSET utf8 COLLATE utf8_general_ci;

删除database: DROP

drop database 数据名;

  • 使用mysqladmin删除数据库
    mysqladmin -u root -p drop 数据库名

选择database:在其他操作前

use 数据库名;

数据类型

数值类型

在这里插入图片描述

日期和时间类型

在这里插入图片描述

字符串类型

在这里插入图片描述
PS: char(n) 和 varchar(n) 中括号中 n 代表字符的个数,并不代表字节个数,比如 CHAR(30) 就可以存储 30 个字符。CHAR 和 VARCHAR 类型类似,但它们保存和检索的方式不同。它们的最大长度和是否尾部空格被保留等方面也不同。在存储或检索过程中不进行大小写转换。

  • varchar不定长比定长char类型更节省空间
  • VARCHAR需要使用1或2个额外字节记录字符串的长度

一对多 vs 多对一 vs 一对一

  • 一个班级对应着多个学生,所以班级表和学生表的关系就是“一对多”。
  • 学生表和班级表是“多对一”的关系。
  • 一个班级总是对应一个教师,班级表和教师表就是“一对一”关系。

主键

  • 主键是关系表中记录的唯一标识。主键的选取非常重要:主键不要带有业务含义,而应该使用BIGINT自增或者GUID类型。主键也不应该允许NULL。

联合主键

  • 通过多个字段唯一标识记录

外键

http://www.cppblog.com/wolf/articles/69089.html

  • 如果一个实体的某个字段指向另一个实体的主键,就称为外键。
  • 被指向的实体,称之为主实体(主表),也叫父实体(父表)。
  • 负责指向的实体,称之为从实体(从表),也叫子实体(子表)
[CONSTRAINT symbol] FOREIGN KEY [id] (index_col_name, ...)
REFERENCES tbl_name (index_col_name, ...)
[ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]
[ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]

CONSTRAINT 'xiaodi_ibfk_1' FOREIGN KEY ('dage_id') REFERENCES 'dage' ('id')

  • dage中id为主键

级联: CASCADE

创建table: CREATE

CREATE TABLE table_name (column_name column_type)

  • eg:
CREATE TABLE IF NOT EXISTS `runoob_tbl`(
   `runoob_id` INT UNSIGNED AUTO_INCREMENT,
   `runoob_title` VARCHAR(100) NOT NULL,
   `runoob_author` VARCHAR(40) NOT NULL,
   `submission_date` DATE,
   PRIMARY KEY ( `runoob_id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

实例解析:

  • NOT NULL:在操作数据库时如果输入该字段的数据为NULL,就会报错。
  • AUTO_INCREMENT定义列为自增的属性,一般用于主键,数值会自动加1。
    • 一般使用BIGINT类型。
      • 如果使用INT自增类型,那么当一张表的记录数超过2147483647(约21亿)时,会达到上限而出错。使用BIGINT自增类型则可以最多约922亿亿条记录。
  • PRIMARY KEY关键字用于定义列为主键。 您可以使用多列来定义主键,列间以逗号分隔。
  • ENGINE 设置存储引擎,CHARSET 设置编码。

删除table: DROP

DROP TABLE table_name

DROP TABLE IF EXISTS 'table_name'

插入数据: INSERT

INSERT INTO table_name ( field1, field2,...fieldN )
                       VALUES
                       ( value1, value2,...valueN );

INSERT INTO runoob_tbl 
    -> (runoob_title, runoob_author, submission_date)
    -> VALUES
    -> ("学习 PHP", "菜鸟教程", NOW());

查询数据: SELECT

SELECT column_name,column_name
FROM table_name
[WHERE Clause]
[LIMIT N][ OFFSET M]
  • 可以使用**星号(*)**来代替其他字段,SELECT语句会返回表的所有字段数据
  • 使用 WHERE 语句来包含任何条件。
  • 使用 LIMIT 属性来设定返回的记录数。
  • 通过OFFSET指定SELECT语句开始查询的数据偏移量。默认情况下偏移量为0。

聚合查询

SELECT COUNT(*) num FROM students; 设置结果集的列名为num

多表查询

SELECT * FROM FROM <表名1> <别名1>, <表名2> <别名2>

  • 同时从<表1>表和<表2>表的“乘积”,查询数据
  • 使用表名.列名这样的方式来引用列和设置别名,这样就避免了结果集的列名重复问题。

连接查询

  • INNER JOIN(内连接,或等值连接):获取两个表中字段匹配关系的记录。
    • 先确定主表,仍然使用FROM <表1>的语法;
    • 再确定需要连接的表,使用INNER JOIN <表2>的语法
    • 然后确定连接条件,使用ON <条件…>,这里的条件是s.class_id = c.id,表示students表的class_id列与classes表的id列相同的行需要连接;
    • 可选:加上WHERE子句、ORDER BY等子句。
  • LEFT JOIN(左连接):获取左表所有记录,即使右表没有对应匹配的记录。
  • RIGHT JOIN(右连接): 与 LEFT JOIN 相反,用于获取右表所有记录,即使左表没有对应匹配的记录。
  • FULL OUTER JOIN

SELECT ... FROM runoob_tbl a INNER JOIN tcount_tbl b ON a.runoob_author = b.runoob_author;

  • 相当于: SELECT a.runoob_id, a.runoob_author, b.runoob_count FROM runoob_tbl a, tcount_tbl b WHERE a.runoob_author = b.runoob_author;

WHERE子句

  • 使用 AND 或者 OR 指定一个或多个条件
  • WHERE 子句也可以运用于 SQL 的 DELETE 或者 UPDATE 命令。
  • 使用 BINARY 关键字来设定 WHERE 子句的字符串比较是区分大小写的。

SELECT * from runoob_tbl WHERE BINARY runoob_author='runoob.com';

WHERE vs GROUP BY vs HAVING

  • where:数据库中常用的是where关键字,用于在初始表中筛选查询。它是一个约束声明,用于约束数据,在返回结果集之前起作用。

  • group by:对select查询出来的结果集按照某个字段或者表达式进行分组,获得一组组的集合,然后从每组中取出一个指定字段或者表达式的值。

  • having:用于对where和group by查询出来的分组过滤,查出满足条件的分组结果。它是一个过滤声明,是在查询返回结果集以后对查询结果进行的过滤操作。

GROUP BY子句: 根据一个或多个列对结果集进行分组

SELECT column_name, function(column_name) FROM table_name
WHERE column_name operator value
GROUP BY column_name;
  • 统计每个人有多少条记录:SELECT name, COUNT(*) FROM employee_tbl GROUP BY name;

WITH ROLLUP: 在分组统计数据基础上再进行相同的统计

SELECT name, SUM(singin) as singin_count FROM employee_tbl GROUP BY name WITH ROLLUP;

HAVING

  • 显示每个地区的总人口数和总面积,仅显示那些面积超过1000000的地区。
SELECT region, SUM(population), SUM(area)
FROM bbc
GROUP BY region
HAVING SUM(area)>1000000

更新指定行数据: UPDATE

UPDATE table_name SET field1=new_value1, field2=new_value2 [WHERE Clause]

  • 将字段中的特定字符串批量修改为其他字符串
    UPDATE table_name SET field=REPLACE(field, 'old-string', 'new-string') [WHERE Clause]

删除记录: DELETE

DELETE FROM table_name [WHERE Clause]

DELETE vs DROP vs TRUNCATE

  • delete,drop,truncate 都有删除表的作用,区别在于:
    • delete 和 truncate 仅仅删除表数据,drop 连表数据和表结构一起删除,打个比方,delete 是单杀,truncate 是团灭,drop 是把电脑摔了。
      2、delete 是 DML 语句,操作完以后如果没有不想提交事务还可以回滚,truncate 和 drop 是 DDL 语句,操作完马上生效,不能回滚
      3、执行的速度上,drop>truncate>delete

LIKE子句

SELECT * FROM table_name WHERE field1 LIKE condition1 [AND [OR]] filed2 = 'somevalue'

  • 使用百分号 **%**字符来表示任意字符
  • 如果没有使用百分号 %, LIKE 子句与等号 = 的效果是一样的。
  • 模糊匹配
    • %:表示任意 0 个或多个字符。可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示。
    • _:表示任意单个字符。匹配单个任意字符,它常用来限制表达式的字符长度语句。
    • []:表示括号内所列字符中的一个(类似正则表达式)。指定一个字符、字符串或范围,要求所匹配对象为它们中的任一个
    • [^] :表示不在括号所列之内的单个字符。其取值和 [] 相同,但它要求所匹配对象为指定字符以外的任一个字符。
    • 查询内容包含通配符时,由于通配符的缘故,导致我们查询特殊字符 “%”、“_”、“[” 的语句无法正常实现,而把特殊字符用 “[ ]” 括起便可正常查询。

UNION操作符:连接两个以上的 SELECT 语句的结果组合到一个结果集合中

SELECT expression1, expression2, ... expression_n
FROM tables [WHERE conditions]
UNION [ALL | DISTINCT]
SELECT expression1, expression2, ... expression_n
FROM tables [WHERE conditions];
  • DISTINCT: 可选,删除结果集中重复的数据。默认情况下 UNION 操作符已经删除了重复数据,所以 DISTINCT 修饰符对结果没啥影响。
  • ALL: 可选,返回所有结果集,包含重复数据。

排序: ORDER BY

SELECT field1, field2,...fieldN FROM table_name1, table_name2... ORDER BY field1 [ASC [DESC][默认 ASC]], [field2...] [ASC [DESC][默认 ASC]]

  • 如果字符集采用的是 utf8(万国码),需要先对字段进行转码然后排序 ... ORDER BY CONVERT(runoob_title using gbk)

NULL处理

当提供的查询条件字段为 NULL 时,该命令可能就无法正常工作。

=》

  • IS NULL: 当列的值是 NULL,此运算符返回 true。
  • IS NOT NULL: 当列的值不为 NULL, 运算符返回 true。
  • <=>: 比较操作符(不同于 = 运算符),当比较的的两个值相等或者都为 NULL 时返回 true。

SELECT * FROM runoob_test_tbl WHERE runoob_count IS NULL;

事务:主要用于处理操作量大,复杂度高的数据。

  • 在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。
  • 事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行。
  • 事务用来管理 insert,update,delete 语句
  • 一般来说,事务是必须满足4个条件(ACID)原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。
    • 隔离性
      • 读未提交(Read uncommitted)
      • 读提交(read committed)
      • 可重复读(repeatable read)
      • 串行化(Serializable)

ALTER命令: 修改数据表名或者修改数据表字段(DROP\ADD\MODIFY)

  • 删除:ALTER TABLE table_name DROP col_name;
  • 添加:ALTER TABLE table_name ADD i INT;
    • 指定新增字段的位置,可以使用MySQL提供的关键字 FIRST (设定位第一列), AFTER 字段名(设定位于某个字段之后)
  • 修改字段类型及名称
    • ALTER TABLE testalter_tbl MODIFY c CHAR(10);
    • ALTER TABLE testalter_tbl CHANGE old_name new_name BIGINT;

索引

  • 索引是关系数据库中对某一列或多个列的值进行预排序的数据结构。
  • 分类
    • 单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引。
    • 组合索引,即一个索引包含多个列。
  • 实际上,索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。
  • 缺点:
    • 虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。
    • 建立索引会占用磁盘空间的索引文件。

基本操作

创建索引

CREATE INDEX indexName ON table_name (column_name)

修改表结构(添加索引)

ALTER table tableName ADD INDEX indexName(columnName)

创建表的时候直接指定

CREATE TABLE mytable(  
ID INT NOT NULL,   
username VARCHAR(16) NOT NULL,  
INDEX [indexName] (username(length))  
);  

删除索引

DROP INDEX [indexName] ON mytable;

唯一索引(UNIQUE INDEX): 索引列的值必须唯一,但允许有空值

  • 在设计关系数据表的时候,看上去唯一的列,例如身份证号、邮箱地址等,因为他们具有业务含义,因此不宜作为主键。但是,这些列根据业务要求,又具有唯一性约束:即不能出现两条记录存储了同一个身份证号。这个时候,就可以给该列添加一个唯一索引。

临时表:只在当前连接可见

复制表

元数据

重复数据处理

插入

  • PRIMARY KEY
  • UNIQUE
    • 如果我们设置了唯一索引,那么在插入重复数据时,SQL 语句将无法执行成功,并抛出错。
      • INSERT IGNORE INTO 会忽略数据库中已经存在的数据,如果数据库没有数据,就插入新的数据,如果有数据的话就跳过这条数据。这样就可以保留数据库中已经存在数据,达到在间隙中插入数据的目的。

管理MySQL

  • 列出所有数据库 SHOW DATABASES;
  • 列出当前数据库的所有表 SHOW TABLES;
  • 查看一个表的结构 DESC students;
  • 查看创建表的SQL语句 SHOW CREATE TABLE students;
  • 退出 EXIT