至今为止,关系数据库 是最常用的数据库类型,关系数据库由关系组成,这些关系通常称为 表格。
表格中的每一列都有唯一的名称,包含不同的数据,列也叫做域或者属性。
每一行有对应每一列的单个 值 组成,每个值必须与该列定义的数据类型相同。
表中的 标志列 称为 键 或者 主键,通常数据库由多个表组成,可以使用键作为表格之间的引用。一个表里的一列标志列用于读取另一个表的信息,那么这个键就叫做 外键。
数据库整套表格的完整设计称为数据库的 模式,它是数据库的设计蓝图,这个模式应该表示表格及表格的列、每个表的主键和外键。一个模式不会好汉任何数据。
设计数据库时,需要注意以下几点:
- 避免保存亢余数据,理由除了空间浪费外,还可能会导致数据更新的不一致,也就是说,在修改数据库之后容易产生数据不一致,数据的完整性将被破坏,
- 避免多个空属性的设计,它会大大地浪费空间同时还可能导致误会。
1 创建用户、设置用户权限
在官网下载完mysql,window系统需要在环境变量里添加路径,例如添加 C:\Program Files\MySQL\MySQL Server 8.0\bin
。添加完路径之后就可以在命令行输入 mysql -u username -p
以进入MySQL了。
创建用户可以使用 create user username identified by password
的语句;
而授予用户权限可以使用 grant
命令,其语法是:
GRANT privileges
on item
TO user_name
[WITH [GRANT OPTION | limit_options]]
其中:
privileges
:表示设置的用户权限,包括:
- SELECT
- INSERT
- UPDATE:允许修改表里数值
- DELETE
- INDEX:允许创建和拖动特定表索引
- ALTER:允许改变现存的结构,如可添加列,重命名列或表,修改猎德数据类型
- CREATE:允许创建数据库或表
- DROP:允许删除数据库或表
item
:表示权限所应用的数据库或表,形式如dbname.*
,可以将项目制定为*.*
,即将权限应用到所有数据库GRANT OPTION
:表示该用户也有创建新用户的权利
2 创建数据库
使用 create datebase dbname
的形式可以 创建数据库,然后使用 use dbname;
的形式来使用数据库。
2.1 关键字
not null
:表示该列属性必须有一个值AUTO_INCREMENT
:它是一个特殊特性,在整数 列中使用,它的用途是当往该列表中插入数据时,如果该列为空,则自动生成一个比本列中最大值更要大的数值,每个表中只能有一个这样的值,且指定该关键字的列一定是索引列primary key
:主键,还可以单独提出来,使用primary key(a, b)
的形式定义多个主键unsigned
:表示只能是整数或者0
2.2 列的类型
MySQL 的列数据类型大致分为:数字、日期、时间以及字符串,其中每个类型又包含了多个类型。
2.2.1 数字
数字类型分为整数和浮点数。使用浮点数的时候可以指定显示宽度以及小数点后的位数。如:
create table books {
price floate(4, 2)
}
// 前者数字表示数据宽度,后者表示小数点后位数
整数的类型:
tinyint[m]
/BIT
/BOOL
:取值范围是-127~128
或0~255
smallint[m]
:取值范围是-32768~32767
或0~65535
mediumint[m]
:取值范围-8388608~8388607
或0~16777215
int[m]
/integer[m]
:取值范围-2^31~2^31-1
或2^32-1
bitint
:取值范围-2^63~2^63-1
或2^64
浮点的类型:
flpat(精度)
:取决于精度float[(M, D)]
:类似于float(4)
double[(M, D)]
:类似于float(8)
2.2.2 日期和事件类型
使用以下这些类型,可以以字符串或数字的格式输入数据:
date
:1000-01-01~9999-12-31
time
:-838:59:59~838:59:59
datetime
:1000-01-01 00:00:00~9999-12-31 23:59:59
year[(2|4)]
:70~69(1970~2069)
或1901~2155
timestamp[(m)]
:其中根据m的数值变化而变化
- 默认:YYYYMMDDHHMMSS
timestamp(2)
:YYtimestamp(4)
:YYMMtimestamp(6)
:YYMMDDtimestamp(8)
:YYYYMMDDtimestamp(10)
:YYMMDDHHMMtimestamp(12)
:YYMMDDHHMMSStimestamp(14)
:YYYYMMDDHHMMSS
2.2.3 字符串
字符串类型分为三类:
- 第一类是普通字符串,即小段文本,包括
char
(固定长度字符)类和varchar
(可变长度字符)类:
char[(m)]
可以指定每种类型的长度,存储时会用空格符填补空白,但读取的时候又会取消掉多余的空格符varchar
列宽会随着数据的大小而改变,在存储数据的时候会过滤掉多余的空格。
- 第二类为
TEXT
和BLOB
类型,它们代销可变,适用于长文本或二进制数据,BLOB
全称为 大二进制对象,它支持任何数据如图像或声音数据,而TEXT
类型与BLOB
的不同在于,TEXT
类型区分大小写。
TINYBLOB
:255TINYTEXT
:255BLOB
:65535TEXT
:65535MEDIUMBLOB
:16777215MEDIUMTEXT
:16777215LONGBLOB
:4294967295LONGTEXT
:4294967295
- 第三类包括两种特殊类型,
SET
或ENUM
3 SQL
SQL的全称是Structured Query Language,它是访问 关系数据库管理系统 的标准语言,它包含 用于定义数据库的数据定义语言(DLL)和 用于查询数据库的数据操作语言 这两种语言的基础部分,SQL可以用来将数据保存到数据库中,以及从数据库中取回数据。
3.1 insert
语句
insert
语句用于保存数据,它的通常格式是:
insert into tableName [(column1, column2, column3, ...)] values (value1, value2, value2, ...);
当只针对一些列或按照不同的顺序去指定它们时,可以使用以下两种形式:
一:
insert into customers (name, city) values ('seiei', 'beijing');
二:
insert into customers set name = 'seiei', city = 'beijing';
在 insert
语句后面可以添加 low_priority
或 delayed
,其中:
low_priority
:如果在SQL中指定LOW_PRIORITY
,可使写操作的优先级降低,相当于原来的写锁在写操作执行前就会产生,当指定LOW_PRIORITY
后,写锁在写操作执行时才会产生,因此可降低读操作的等待时间,虽然修改LOW_PRIORITY
可降低读操作的等待时间,但由于降低了写操作的优先级,写操作需等待读锁都释放后才可执行,使MySQL队列中有可能堆积写操作delayed
:意味着插入数据会被缓存,如果服务器繁忙会运行其他查询,而不是等待insert
操作完成ignore
:ignore
存放在前两个关键字之后,作用是如果尝试插入如何可能导致重复唯一键的记录行都会被忽略
3.2 查询数据(select
语句)
select
语句可以通过匹配表中 指定规则的行 从数据库中获取数据,查找返回的可以看做是返回一个表格
select [options] items
[into file_details]
from tables
[where conditions]
[group by order_type]
[having where_definetion]
[order by order_type]
[limit limit_criteria]
[procedure proc_name(arguments)]
[lock_options];
3.2.1 从当个表格中寻找(where
子句)
要访问一个表中行的子集,需要指定一些选择条件,此时可以使用子句 where
,where
字句指定了用于选择特定行的条件,MySQL支持所有比较操作符和正则表达式,常用的比较操作符有:
=
>
<
>=
<=
!=
is not null
is null
between
:测试一个值是否大于或者等于最小值并且小于或等于最大值in
:测试一个值是否在特定的集合里not in
like
:形如name like {'Fred %'}
,这是一个简单的SQ匹配模式,该模式由常规文本和两个字符组成,其中这两个重要的字符分别是:%
表示可以匹配任何数量任意字符,_
表示只匹配一个任意字符not like
regexp
:正则表达式
同时还可以使用 and
和 or
进行组合。
3.2.2 从多个表格中获取数据
要在多个不同的表中获取数据,就需要执行 关联 操作了。
关联的类型大致分为:
- 笛卡尔乘积 / 完全关联 / 交叉关联:所有表所有行的所有关联,在关联表名之间使用逗号或
inner join
或cross join
链接 - 内部关联:如果没有
where
条件就等价于完全关联了,所以一定要使用where
字句使其变成真正的内部关联 - 等价关联:在关联中使用带
=
的条件表达式来匹配不同表中的行 - 左关联:在SQL中使用
left join
关键词,试图匹配表的行,并在不匹配的行中添加null
3.2.2.1 笛卡尔乘积 / 完全关联 / 交叉关联
笛卡尔乘积 / 完全关联 / 交叉关联 其意思是:将多个表列出来,形成一个中间表,该表应该有一行来自所有表的每一行的所有可能组合(注意这里头“中间表”的意思,指的是被操作期间生成的数据库表,而不是操作后生成的表),所有表所有行的所有关联,在关联表名之间使用逗号或 inner join
或 cross join
链接,例如:
select orderid
from orders, customers
where customers.name = 'seiei'
and customers.id = orders.id;
3.2.2.2 左关联
左关联通常用于返回包括左表中的所有记录和右表中匹配条件相等的记录,如果此时右表条件不匹配则返回 null
。
到这还要注意 where
与 on
条件的区别:
- 多表
left join
是会生成一张临时表,并返回给用户,where
条件是针对最后生成的这张临时表进行过滤,过滤掉不符合where
条件的记录,是真正的不符合就过滤掉。 on
条件是对left join
的右表进行条件过滤,但依然返回左表的所有行,右表中没有的补为NULL
,on
条件中如果有对左表的限制条件,无论条件真假,依然返回左表的所有行,但是会影响右表的匹配值。也就是说on
中左表的限制条件只影响右表的匹配内容,不影响返回行数。
当使用 on
条件来表达条件相等的时候,可以使用 using
,形如:
select a.*, b.* from a left join b using(colA);
等价于:
select a.*, b.* from a left join b on a.colA = b.colB;
3.2.3 按顺序获取数据
如果想要按照一定的顺序获取数据,可以使用 order by
字句,该特性可以方便的实现该功能。其默认是升序排列,降序可以在末尾添加 desc
关键字,例如:
select name from customers order by name desc;
3.2.4 分组和合计数据
有时候我们可能需要查找一些平均值什么的,这时可以使用MySQL的合计函数:
avg(列)
:平均值count(项目)
:求出行数:
- 项目只指定一个列名,返回该列非
null
的总行数 - 在列名之前添加
distinct
关键字,返回该列不同值的总行数 - 项目指定
*
,得到包括null
在内的总行数
- 项目只指定一个列名,返回该列非
sum()
:所有值之和min()
max()
std()
/steddev()
在通过使用合计函数获取更多详细信息的时候,还可以使用 group by
子句,从而可以分组查询,计算。同时还可以使用 having
子句来测试一个合计的结果,直接放置在 having
子句之后。
3.2.5 选择返回行的个数 limit
比如博客中主页显示文章的篇数就可以使用 limit
子句实现。如:
select name
from customers
limit 2, 3;
作用是返回3行,从第2行开始(注意:行号从0开始)
3.2.6 使用子查询
子查询是一个嵌套在另一个查询内部的查询,例如:
select customerid
from orders
where amount = (select max(amount) from orders);
3.2.6.1 子查询的操作符
特殊的子查询操作符共以下5个,其中前三个几乎一致:
any
:select c1 from t1 where c1 > any(select c1 from t2);
in
:select c1 from t1 where c1 in (select c1 from t2);
,等价于= any
some
:等价于any
all
:select c1 from t1 where c1 > all(select c1 from t2);
exists
:select isbn, titile from books where not exists (select * from order_items where order_items.isbn = books.isbn);
3.2.6.2 行子查询
select c1,c2,c3
from t1
where (c1,c2,c3) in (select c1,c2,c3 from t2);
3.2.6.3 使用子查询作为临时表
select * from
(select customerid, name from customers where city = 'Box Hill')
as box_hill_customers
3.3 更新数据库记录
从数据库修改数据,可以使用 update
,常用格式是:
update [low_priority] [ignore] tablename
set column1 = expression1, column2 = expressoin2, ...
[where condition]
[order by order_criteria]
[limit number];
例如:
update books
set price = price*1.1
where isbn = 123;
3.4 修改已经创建的表
除了更新行,有时候还需要修改数据库中的表的结构,此时要使用 alter table
语句
alter table [ignore] tablename alteration [, alteration ...]
以下列出常用的 alteration
类型:
add [column] column_description [first | after column]
:添加新列add [column] (column_description, column_description, ...)
:在末尾添加一个或多个新的列drop [column] column
:删除指定的列rename [as] new_table_name
:重新命名一个表change [column] column new_column_description
:修改列,可以修改列的名称,因为new_column_description
中就包含了名称modify [column] column_description
:类似于change
,用于修改列的类型,而不是名称
eg:
alter table customers
modify name char(70) not null;
3.5 删除表中的某个记录、表以及整个数据库
3.5.1 删除表中的某个记录
可以使用 delete
语句,常见格式:
delete [low_priority] [quick] [ignore] from table
[where condition]
[order by order_cols]
[limit number]
例如:
delete from customers
where customerid = 5;
3.5.2 删除表
drop table tableName
3.5.3 删除数据库
drop database databaseName;