mysql
关系型与非关系型数据库区别
关系型:方便在一个表以及多个表之间做非常复杂的数据查询,支持事务
非关系型:基于键值对,数据之间没有藕合性,容易水平扩展
RDBMS术语
数据库: 数据库是一些关联表的集合。
数据表: 表是数据的矩阵。在一个数据库中的表看起来像一个简单的电子表格。
列: 一列(数据元素) 包含了相同的数据, 例如邮政编码的数据。
行:一行(=元组,或记录)是一组相关的数据,例如一条用户订阅的数据。
冗余:存储两倍数据,冗余可以使系统速度更快。
(表的规范化程度越高,表与表之间的关系就越多;查询时可能经常需要在多个表之间进行连接查询;而进行连接操作会降低查询速度。
例如,学生的信息存储在student表中,院系信息存储在department表中。通过student表中的dept_id字段与department表建立关联关系。
如果要查询一个学生所在系的名称,必须从student表中查找学生所在院系的编号(dept_id),然后根据这个编号去department查找系的名称。
如果经常需要进行这个操作时,连接查询会浪费很多的时间。
因此可以在student表中增加一个冗余字段dept_name,该字段用来存储学生所在院系的名称。这样就不用每次都进行连接操作了。)
主键:主键是唯一的。一个数据表中只能包含一个主键。你可以使用主键来查询数据。
外键:外键用于关联两个表。
复合键:复合键(组合键)将多个列作为一个索引键,一般用于复合索引。
索引:使用索引可快速访问数据库表中的特定信息。索引是对数据库表中一列或多列的值进行排序的一种结构。类似于书籍的目录。
参照完整性: 参照的完整性要求关系中不允许引用不存在的实体。与实体完整性是关系模型必须满足的完整性约束条件,目的是保证数据的一致性。
MySQL支持的数据类型(数值、日期/时间、字符串)
数值类型
MySQL支持所有标准SQL数值数据类型。
这些类型包括严格数值数据类型(INTEGER、SMALLINT、DECIMAL和NUMERIC),以及近似数值数据类型(FLOAT、REAL和DOUBLE PRECISION)。
关键字INT是INTEGER的同义词,关键字DEC是DECIMAL的同义词。
BIT数据类型保存位字段值,并且支持MyISAM、MEMORY、InnoDB和BDB表。
作为SQL标准的扩展,MySQL也支持整数类型TINYINT、MEDIUMINT和BIGINT。下面的表显示了需要的每个整数类型的存储和范围。
类型 | 大小 | 范围(有符号) | 范围(无符号) | 用途 |
---|---|---|---|---|
TINYINT | 1 字节 | (-128,127) | (0,255) | 小整数值 |
SMALLINT | 2 字节 | (-32 768,32 767) | (0,65 535) | 大整数值 |
MEDIUMINT | 3 字节 | (-8 388 608,8 388 607) | (0,16 777 215) | 大整数值 |
INT或INTEGER | 4 字节 | (-2 147 483 648,2 147 483 647) | (0,4 294 967 295) | 大整数值 |
BIGINT | 8 字节 | (-9 233 372 036 854 775 808,9 223 372 036 854 775 807) | (0,18 446 744 073 709 551 615) | 极大整数值 |
FLOAT | 4 字节 | (-3.402 823 466 E+38,1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38) | 0,(1.175 494 351 E-38,3.402 823 466 E+38) | 单精度 浮点数值 |
DOUBLE | 8 字节 | (1.797 693 134 862 315 7 E+308,2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) | 0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) | 双精度 浮点数值 |
DECIMAL | 对DECIMAL(M,D) ,如果M>D,为M+2否则为D+2 | 依赖于M和D的值 | 依赖于M和D的值 | 小数值 |
日期和时间类型
表示时间值的日期和时间类型为DATETIME、DATE、TIMESTAMP、TIME和YEAR。
每个时间类型有一个有效值范围和一个"零"值,当指定不合法的MySQL不能表示的值时使用"零"值。
TIMESTAMP类型有专有的自动更新特性,将在后面描述。
类型 | 大小 (字节) | 范围 | 格式 | 用途 |
---|---|---|---|---|
DATE | 3 | 1000-01-01/9999-12-31 | YYYY-MM-DD | 日期值 |
TIME | 3 | '-838:59:59'/'838:59:59' | HH:MM:SS | 时间值或持续时间 |
YEAR | 1 | 1901/2155 | YYYY | 年份值 |
DATETIME | 8 | 1000-01-01 00:00:00/9999-12-31 23:59:59 | YYYY-MM-DD HH:MM:SS | 混合日期和时间值 |
TIMESTAMP | 4 | 1970-01-01 00:00:00/2037 年某时 | YYYYMMDD HHMMSS | 混合日期和时间值,时间戳 |
字符串类型
字符串类型指CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM和SET。该节描述了这些类型如何工作以及如何在查询中使用这些类型。
类型 | 大小 | 用途 |
---|---|---|
CHAR | 0-255字节 | 定长字符串 |
VARCHAR | 0-65535 字节 | 变长字符串 |
TINYBLOB | 0-255字节 | 不超过 255 个字符的二进制字符串 |
TINYTEXT | 0-255字节 | 短文本字符串 |
BLOB | 0-65 535字节 | 二进制形式的长文本数据 |
TEXT | 0-65 535字节 | 长文本数据 |
MEDIUMBLOB | 0-16 777 215字节 | 二进制形式的中等长度文本数据 |
MEDIUMTEXT | 0-16 777 215字节 | 中等长度文本数据 |
LONGBLOB | 0-4 294 967 295字节 | 二进制形式的极大文本数据 |
LONGTEXT | 0-4 294 967 295字节 | 极大文本数据 |
CHAR和VARCHAR类型类似,但它们保存和检索的方式不同。它们的最大长度和是否尾部空格被保留等方面也不同。在存储或检索过程中不进行大小写转换。
BINARY和VARBINARY类类似于CHAR和VARCHAR,不同的是它们包含二进制字符串而不要非二进制字符串。也就是说,它们包含字节字符串而不是字符字符串。这说明它们没有字符集,并且排序和比较基于列值字节的数值值。
BLOB是一个二进制大对象,可以容纳可变数量的数据。有4种BLOB类型:TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB。它们只是可容纳值的最大长度不同。
有4种TEXT类型:TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT。这些对应4种BLOB类型,有相同的最大长度和存储需求。
Mysql中where的条件判断
操作符 | 描述 | 实例 |
---|---|---|
= | 等号,检测两个值是否相等,如果相等返回true | (A = B) 返回false。 |
<>, != | 不等于,检测两个值是否相等,如果不相等返回true | (A != B) 返回 true。 |
> | 大于号,检测左边的值是否大于右边的值, 如果左边的值大于右边的值返回true | (A > B) 返回false。 |
< | 小于号,检测左边的值是否小于右边的值, 如果左边的值小于右边的值返回true | (A < B) 返回 true。 |
>= | 大于等于号,检测左边的值是否大于或等于右边的值, 如果左边的值大于或等于右边的值返回true | (A >= B) 返回false。 |
<= | 小于等于号,检测左边的值是否小于于或等于右边的值, 如果左边的值小于或等于右边的值返回true | (A <= B) 返回 true。 |
关于外键
MariaDB [oldboy]> create table student2 ( -> id int(5) not null, -> name char(8) not null, -> class_id int(5) not null, -> primary key (id), -> key fk_class_key (class_id), -> constraint fk_class_key foreign key (class_id) references class (id));
此时如果class 表中不存在id 1,student表也插入不了,这就叫外键约束 MariaDB [oldboy]> insert into student2(id,name,class_id) values(1,"alex",1); ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`oldboy`.`student2`, CONSTRAINT `fk_class_key` FOREIGN KEY (`class_id`) REFERENCES `class` (`id`)) MariaDB [oldboy]> insert into class(id,name) values(1,"linux"); Query OK, 1 row affected (0.01 sec) MariaDB [oldboy]> insert into student2(id,name,class_id) values(1,"alex",1); Query OK, 1 row affected (0.00 sec) #如果有student表中跟这个class表有关联的数据,你是不能删除class表中与其关联的纪录的 MariaDB [oldboy]> delete from class where id=1; ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`oldboy`.`student2`, CONSTRAINT `fk_class_key` FOREIGN KEY (`class_id`) REFERENCES `class` (`id`))
MySQL NULL值处理
WHERE 子句来读取数据表中的数据,但是当提供的查询条件字段为 NULL 时,该命令可能就无法正常工作。
为了处理这种情况,MySQL提供了三大运算符:
IS NULL: 当列的值是NULL,此运算符返回true。
IS NOT NULL: 当列的值不为NULL, 运算符返回true。
<=>: 比较操作符(不同于=运算符),当比较的的两个值为NULL时返回true。
关于 NULL 的条件比较运算是比较特殊的。你不能使用 = NULL 或 != NULL 在列中查找 NULL 值 。
在MySQL中,NULL值与任何其它值的比较(即使是NULL)永远返回false,即 NULL = NULL 返回false 。
MySQL中处理NULL使用IS NULL和IS NOT NULL运算符。
Mysql命令
mysqladmin -u root password "new_password"; # 命令行设置mysql的root密码 # 添加mysql用户:password()函数对密码进行加密存储 insert into mysql.user (host,user,password,select_priv,insert_priv,update_priv) -> values("localhost","guest",password("guest"),"Y","Y","Y"); 你可以在创建用户时,为用户指定权限,在对应的权限列中,在插入语句中设置为 'Y' 即可,用户权限列表如下: Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Reload_priv, Shutdown_priv,Process_priv,File_priv,Grant_priv,References_priv,Index_priv,Alter_priv # 创建mysql用户 grant select,insert,update,delete,create,drop -> on test.* -> to "test"@"localhost" -> identified by "test"; # 设置密码 flush privileges; # 刷新权限 USE 数据库名 :选择要操作的Mysql数据库,使用该命令后所有Mysql命令都只针对该数据库。 SHOW DATABASES: 列出 MySQL 数据库管理系统的数据库列表。 SHOW TABLES: #显示指定数据库的所有表,使用该命令前需要使用 use命令来选择要操作的数据库。 SHOW COLUMNS FROM 数据表/ desc 数据表: #显示数据表的属性,属性类型,主键信息 ,是否为 NULL,默认值等其他信息。 create database testdb charset "utf8"; #创建一个叫testdb的数据库,且让其支持中文 drop database testdb; #删除数据库 SHOW INDEX FROM 数据表 #显示数据表的详细索引信息,包括PRIMARY KEY(主键)。 create table table_name(column_name column_type); #创建数据表 eg: create table student( -> stu_id int not null auto_increment, -> name char(32) not null, -> age int not null, -> register_date timestamp not null default current_timestamp, -> primary key (stu_id)); insert into table_name (field1,field2,...,fieldN) values (value1,value2,...valueN); # 插入数据 eg: insert into student (name,age) values ("alex li",22); # 查询语句,offset开始查询的数据偏移量,要与limit结合起来用 select column_name,column_name from table_name [where Clause] [limit N] [offset M]; eg: select name,register_date from student where age < 25 limit 2 offset 0; select name,register_date from student limit 1, 3; # limit后面是从第1条开始读,读取3条信息。 update table_name set field1=new_value1,field2=new_value2 [where Clause]; # update 更改数据 delete from table_name [where Clause]; # 删除表中的数据 select * from student where name like binary "%Li"; # like匹配,只匹配大写 select * from student where name like "%Li"; # 匹配大小写 # 排序,默认是asc排序 select field1,field2,..fieldN table_name,[table_name...] order by field1,[field2..] [asc|desc] select coalesce(name,"总数") as total ,sum(age) as sum from student group by name with rollup; # group by配合聚合函数对分组信息进行统计 # coalesce: 假如某个字段默认是null,你想其返回的不是null,而是比如0或其他值,可以使用这个函数 # with rollup 得到group by 汇总信息 alter 修改数据表名或者修改数据表字段 删除,添加或修改表字段 alter table student drop register_date; # 从student表中删除register_date 修改字段类型及名称(使用alter中的modif、change) alter table student modify name char(5); # modify修改字段类型 alter table student change stu_id id int(5); # change修改字段、字段类型 修改NULL值、默认值 alter table student modify name char(8) not null default 100; 修改表名 alter table student rename to class; # 修改表名 使用ALTER 命令添加和删除索引 ALTER TABLE tbl_name ADD PRIMARY KEY (column_list): 该语句添加一个主键,这意味着索引值必须是唯一的,且不能为NULL。 ALTER TABLE tbl_name ADD UNIQUE index_name (column_list): 这条语句创建索引的值必须是唯一的(除了NULL外,NULL可能会出现多次)。 ALTER TABLE tbl_name ADD INDEX index_name (column_list): 添加普通索引,索引值可出现多次。 ALTER TABLE tbl_name ADD FULLTEXT index_name (column_list):该语句指定了索引为 FULLTEXT ,用于全文索引。 以下实例为在表中添加索引。 mysql> ALTER TABLE testalter_tbl ADD INDEX (c); mysql> ALTER TABLE testalter_tbl DROP INDEX (c); 主键只能作用于一个列上,添加主键索引时,你需要确保该主键默认不为空(NOT NULL)。实例如下: mysql> ALTER TABLE testalter_tbl MODIFY i INT NOT NULL; mysql> ALTER TABLE testalter_tbl ADD PRIMARY KEY (i); mysql> ALTER TABLE testalter_tbl DROP PRIMARY KEY; 删除指定时只需指定PRIMARY KEY,但在删除索引时,你必须知道索引名。
Mysql连接(多个数据表中读取数据)
按功能分类: inner join(内连接,或等值连接):获取两个表中字段匹配关系记录 left join(左连接):获取左表所有记录,即使右表没有对应匹配的记录 right join(右连接):与left join相反,用于获取右表所有记录,即使左表没有对应匹配记录 select * from a INNER JOIN b on a.a = b.b; # inner join交集 select a.*,b.* from a,b where a.a = b.b; # 交集 select * from a LEFT JOIN b on a.a = b.b; # 取左边表的所有数据 select * from a RIGHT JOIN b on a.a = b.b; # 取右边表的所有数据 select * from a FULL JOIN b on a.a = b.b; # 取左右两边的所有数据(合集) mysql不支持 select * from a left join b on a.a = b.b UNION select * from a right join b on a.a = b.b; # 合集
事务
MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!
在MySQL中只有使用了Innodb数据库引擎的数据库或表才支持事务
事务处理可以用来维护数据库的完整性,保证成批的SQL语句要么全部执行,要么全部不执行
事务用来管理insert,update,delete语句
一般来说,事务是必须满足4个条件(ACID): Atomicity(原子性)、Consistency(稳定性)、Isolation(隔离性)、Durability(可靠性)
1、事务的原子性:一组事务,要么成功;要么撤回。
2、稳定性 : 有非法数据(外键约束之类),事务撤回。
3、隔离性:事务独立运行。一个事务处理后的结果,影响了其他事务,那么其他事务会撤回。事务的100%隔离,需要牺牲速度。
4、可靠性:软、硬件崩溃后,InnoDB数据表驱动会利用日志文件重构修改。可靠性和高速度不可兼得, innodb_flush_log_at_trx_commit选项 决定什么时候吧事务保存到日志里。
Mysql控制台使用事务来操作
MariaDB [oldboy]> begin; # 开启事务
MariaDB [oldboy]> insert into a (a) values (555); # 执行事务语句
MariaDB [oldboy]> rollback; # 回滚(不想提交就执行回滚,那样开启事务的就不会提交)
MariaDB [oldboy]> commit; # 提交
索引
MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。 创建索引时,你需要确保该索引是应用在 SQL 查询语句的条件(一般作为 WHERE 子句的条件)。 实际上,索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。 索引分类: 单列索引:一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引。 组合索引:一个索包含多个列。 索引缺点: 虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。 更新表时,MySQL不仅要保存数据,还要保存一下索引文件。建立索引会占用磁盘空间的索引文件。
普通索引: 创建索引: CREATE INDEX indexName ON mytable(username(length)); # indexName为key_name,length:字符长度 alter table student add column sex char(3); # 添加列 alter table student add index (sex(3)); # 添加索引 MariaDB [oldboy]> create table mytable ( # 创建表的时候直接指定 -> id int not null, -> username varchar(16) not null, -> index indexName (username(15))); DROP INDEX indexName ON mytable; # 删除表格中的索引名 唯一索引:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一 创建索引: create unique index username_key on mytable(username(16)) # key_name 不能跟已存在的索引相同 alter table mytable add unique key_user (username(15)); # 创建唯一索引 create table my ( id int not null, username char(4) not null, unique key_user (username(3))); # 唯一索引不支持int类型
show grants for caoy; 查caoy用户的权限
show create database oldboy; 查看对应的数据库的创建命令
create database oldboy charset "utf8"; 创建库时使它字符类型为utf8
create table student(stu_id int auto_increment, name char(32) not null, age int not null, register_date timestamp not null default current_timestamp, primary key (stu_id));
自增 自动设置时间为创建时间 设置主键,默认不能为空
select coalesce(name,"总数") as total ,sum(age) as sum from student group by name with rollup;