一、数据库基本概念
1、数据(data)
• 描述事物的符号记录
• 包括数字,文字,图形,图像,声音,档案记录等
• 以“记录”形式按统一的格式进行存储
2、表
• 将不同的记录组织在一起
• 用来存储具体数据
3、数据库
• 表的集合,是存储数据的仓库
• 以一定的组织方式存储的相互有关的数据集合
4、数据库管理系统(DBMS)
• 是实现对数据库资源有效组织、管理和存取的系统软件
5、数据库系统
• 是一个人机系统,由硬件、os、数据库、DBMS、应用软件和数据库用户组成
• 用户可以通过DBMS或应用程序操作数据库
6、访问数据库的流程
二.数据库系统发展史
1.第一代数据库
• 自20世纪60年代起,第一代数据库系统问世
• 是层次模型与网状模型的数据库系统
• 为统一管理和共享数据提供了有力的支撑
2.第二代数据库
• 20世纪70年代,第二代数据库—关系数据库开始出现
• 20世纪80年代,IBM公司的关系数据库系统DB2问世,开始逐步取代层次与网状模型的据库,成为行业主流
• 到目前为止,关系数据库系统仍占领数据库应用的主要地位
3.第三代数据库
• 自20世纪80年代开始,适应不同领域的新型数据库系统不断涌现
• 面向对象的数据库系统,实用性强,适应面广
• 20世纪90年代后期,形成了多种数据库系统共同支撑应用的局面
• 一些新的元素被添加进主流数据库系统中
例如,Oracle支持的 “关系-对象"数据库模型
三、主流数据库介绍
1.SQL Server (微软公司产品)
• 面向Windows操作系统
• 简单、易用
2、Oracle (甲骨文公司产品)
• 面向所有主流平台,
• 安全、完善,操作复杂
3、DB2 (IBM公司产品)
• 面向所有主流平台
• 大型、安全、完善
4.MySQL (甲骨文公司收购)
• 免费、开源、体积小
四、数据库类型
1. 关系数据库
关系数据库系统是基于关系模型的数据库系统
关系模型的数据结构使用简单易懂的二维数据表
关系模型可用简单的“实体-关系”(E-R)图来表示
E-R图中包含了实体(数据对象)、关系和属性三个要素
(1)实体
也称为实例,对应现实世界中可区别于其他对象的“事件”或“事务”
如上图的银行客户、银行账户
(2)属性
实体所具有的某一特性,一个实体可以有多个属性
如上图的“银行客户”实体集中的每个实体均具有姓名、住址、电话等属性
(3)联系
实体集之间的对应关系称为联系,也称为关系
如银行客户和银行账户之间存在“储蓄”的关系
关系数据库的存储结构是二维表格,在每个二维表中
• 每一行称为一条记录,用来描述一个对象的信息
• 每一列称为一个字段,用来描述对象的一个属性
(4)关系数据库
• Oracle , MySQL
• SQLServer、Sybase
• Informix、access
• DB2、FoxPRO
2、非关系数据库
非关系数据库也被称作NoSQL (Not Only SQL)
存储数据不以关系模型为依据,不需要固定的表格式
1、非关系型数据库的优点
• 数据库可高并发读写
• 对海数据高效率存储与访问
• 数据库具有高扩展性与高可用性
2、常用的非关系数据库
Redis、mongoDB等
3、总结
非关系数据库大部分以键值对的方式进行存储(例如:name=xxx),之间没有特定的联系,安全性不是很高,非关系数据库很多将数据是写在内存当中,所以读写速度
三、MySQL数据库
1.MySQL数据库
一款深受欢迎的开源关系型数据库
Oracle旗下的产品
遵守GPL协议,可以免费使用与修改
特点:
性能卓越、服务稳定
开源、无版权限制、成本低
多线程、多用户
基于C/S(客户端/服务器)架构
安全可靠
2、MySQL商业版与社区版
MySQL商业版是由MySQL AB公司负责开发与维护,需要付费才能使用
MySQL社区版是由分散在世界各地的MySQL开发者、爱好者一起开发与维护,可以免费用
两者区别
商业版组织管理与测试环节更加严格,会比社区版更稳定
商业版不遵守GPL,社区版遵从GPL可以免费使用
商业版可获得7*24小时的服务,社区版则没有
3. MySQL产品阵营
第一阵营:5.0-5.1阵营,可说是早期产品的延续
第二阵营:5.4-5.7阵营,整合了MySQL AB公司、社区和第三方公司开发的存储引擎,从提高性能
第三阵营:6.0-7.1阵营,就是MySQL Cluster版本,为适应新时代对数据库的集群需求而发
第四阵营:8.0阵营,最新版本,由于新版本未知BUG多、兼容性差等特点,暂时使用的多
下载网址:http://www.dev.mysql.com/downloads
4. 常用的数据类型
主要包括以下五大类:
整数类型:BIT、BOOL、TINY INT、SMALL INT、MEDIUM INT、 INT、 BIG INT
浮点数类型:FLOAT、DOUBLE、DECIMAL
字符串类型:CHAR、VARCHAR、TINY TEXT、TEXT、MEDIUM TEXT、LONGTEXTTINY BLOB、BLOB、MEDIUM BLOB、LONG BLOB
日期类型:Date、DateTime、TimeStamp、Time、Year
其他数据类型:BINARY、VARBINARY、ENUM、SET、Geometry、Point、MultiPointLineString、MultiLineString、Polygon、GeometryCollection等
1、整型
MySQL数据类型 | 含义(有符号) |
---|---|
tinyint(m) | 1个字节 范围(-128~127) |
smallint(m) | 2个字节 范围(-32768~32767) |
mediumint(m) | 3个字节 范围(-8388608~8388607) |
int(m) | 4个字节 范围(-2147483648~2147483647) |
bigint(m) | 8个字节 范围(±9.22*10的18次方) |
取值范围如果加了unsigned,则最大值翻倍,如tinyint unsigned的取值范围为(0~256)。
int(m)里的m是表示SELECT查询结果集中的显示宽度,并不影响实际的取值范围,没有响到显示的宽度,不知道这个m有什么用。
2、浮点型(float和double)
MySQL数据类型 | 含义 |
---|---|
float(m,d) | 单精度浮点型 8位精度(4字节) m总个数,d小数位 |
double(m,d) | 双精度浮点型 16位精度(8字节) m总个数,d小数位 |
设一个字段定义为float(6,3),如果插入一个数123.45678,实际数据库里存的是123.457,总个数还以实际为准,即6位。整数部分最大是3位,如果插入数12.123456,存储12.1234,如果插入12.12,存储的是12.1200.
3、定点型
浮点型在数据库中存放的是近似值,而定点类型在数据库中存放的是精确值。
decimal(m,d) 参数m<65 是总个数,d<30且 d<m 是小数位。
4、字符串(char,varchar,_text)
MySQL数据类型 | 含义 |
---|---|
char(n) | 固定长度,最多255个字符 |
varchar(n) | 固定长度,最多65535个字符 |
tinytext | 可变长度,最多255个字符 |
text 可变长度, | 最多65535个字符 |
mediumtext | 可变长度,最多2的24次方-1个字符 |
longtext | 可变长度,最多2的32次方-1个字符 |
char和varchar:
1.char(n) 若存入字符数小于n,则以空格补于其后,查询之时再将空格去掉。所以char型存储的字符串末尾不能有空格,varchar不限于此。
2.char(n) 固定长度,char(4)不管是存入几个字符,都将占用4个字节,varchar是存入的际字符数+1个字节(n<=255)或2个字节(n>255),
所以varchar(4),存入3个字符将占用4个字节。
3.char类型的字符串检索速度要比varchar类型的快。
varchar和text:①.varchar可指定n,text不能指定,内部存储varchar是存入的实际字符数+1个字节(n<=255)或2个字节(n>255),text是实际字符数+2个字节。
②.text类型不能有默认值。
③.varchar可直接创建索引,text创建索引要指定前多少个字符。varchar查询速度快于text在都创建索引的情况下,text的索引似乎不起作用。
5.二进制数据(_Blob)
1._BLOB和_text存储方式不同,_TEXT以文本方式存储,英文存储区分大小写,而_Blo是以二进制方式存储,不分大小写。
2._BLOB存储的数据只能整体读出。
3._TEXT可以指定字符集,_BLO不用指定字符集。
6.日期时间类型
MySQL数据类型 | 含义 |
---|---|
date | 日期 ‘2008-12-2’ |
time | 时间 ‘12:25:36’ |
datetime | 日期时间 ‘2008-12-2 22:06:44’ |
timestamp | 自动存储记录修改时间 |
若定义一个字段为timestamp,这个字段里的时间数据会随其他字段修改的时候自动新,所以这个数据类型的字段可以存放这条记录最后被修改的时间。
7、数据类型的属性
MySQL关键字 | 含义 |
---|---|
NULL | 数据列可包含NULL值 |
NOT NULL | 数据列不允许包含NULL值 |
DEFAULT | 默认值 |
PRIMARY KEY | 主键 |
UNIQUE KEY | 唯一约束 |
AUTO_INCREMENT | 自动递增,适用于整数类型 |
UNSIGNED | 无符号 |
CHARACTER SET name | 指定一个字符集 |
唯一约束(Unique Key)是指所有记录中字段的值不能重复出现。例如,为 id 字段加上一性约束后,每条记录的 id 值都是唯一的,不能出现重复的情况。如果其中一条记录的 id 为‘001’,那么该表中就不能出现另一条记录的 id 值也为‘001’。
唯一约束与主键约束相似的是它们都可以确保列的唯一性。不同的是,唯一约束在一个表可有多个,并且设置唯一约束的列允许有空值,但是只能有一个空值。而主键约束在一个表只能有一个,且不允许有空值。比如,在用户信息表中,为了避免表中用户名重名,可以把用户名设置为唯一约束。
8、MySQL数据类型的长度和范围
各数据类型及字节长度:
数据类型 | 字节长度 | 范围或用法 |
---|---|---|
Bit | 1 | 无符号[0,255],有符号[-128,127],备注:BIT和BOOL布尔型都占用1字节 |
TinyInt | 1 | 整数[0,255] |
SmallInt | 2 | 无符号[0,65535],有符号[-32768,32767] |
MediumInt | 3 | 无符号[0,224-1],有符号[-223,2^23-1]] |
Int | 4 | 无符号[0,232-1],有符号[-231,2^31-1] |
BigInt | 8 | 无符号[0,264-1],有符号[-263 ,2^63 -1] |
Float(M,D) | 4 | 单精度浮点数。这里的D是精度,如果D<=24则为默认的FLOAT,如果D>24则会自动被转换为DOUBLE型。 |
Double(M,D) | 8 | 双精度浮点。 |
Decimal(M,D) | M+1或M+2 | 未打包的浮点数,用法类似于FLOAT和DOUBLE,如果在ASP中使用到Decimal数据类型,直接从数据库读出来的Decimal可能需要先转换成Float或Double类型后再进行运算。 |
Date | 3 | 以YYYY-MM-DD的格式显示,比如:2009-07-19 |
Date Time | 8 | 以YYYY-MM-DD HH:MM:SS的格式显示,比如:2009-07-19 11:22:30 |
TimeStamp | 4 | 以YYYY-MM-DD的格式显示,比如:2009-07-19 |
Time | 3 | 以HH:MM:SS的格式显示。比如:11:22:30 |
Year | 1 | 以YYYY的格式显示。比如:2009 |
Char(M) | M | 定长字符串。 |
VarChar(M) | M | 变长字符串,要求M<=255 |
Binary(M) | M | 类似Char的二进制存储,特点是插入定长不足补0 |
VarBinary(M) | M | 类似VarChar的变长二进制存储,特点是定长不补0 |
Tiny Text | Max:255 | 大小写不敏感 |
Text | Max:64K | 大小写不敏感 |
Medium Text | Max:16M | 大小写不敏感 |
Long Text | Max:4G | 大小写不敏感 |
TinyBlob | Max:255 | 大小写敏感 |
Blob | Max:64K | 大小写敏感 |
MediumBlob | Max:16M | 大小写敏感 |
LongBlob | Max:4G | 大小写敏感 |
Enum | 1或2 | 最大可达65535个不同的枚举值 |
Set | 可达8 | 最大可达64个不同的值 |
9、使用建议
1、在指定数据类型的时候一般是采用从小原则,比如能用TINY INT的最好就不用INT,用FLOAT类型的就不用DOUBLE类型,这样会对MYSQL在运行效率上提高很大,尤其是大据量测试条件下。
2、不需要把数据表设计的太过复杂,功能模块上区分或许对于后期的维护更为方便,慎出现大杂烩数据表
3、数据表和字段的起名字也是一门学问
4、设计数据表结构之前请先想象一下是你的房间,或许结果会更加合理、高效
5、数据库的最后设计结果一定是效率和可扩展性的折中,偏向任何一方都是欠妥的
四、MySQL基本操作
1. SQL语言分类
SQL语言
DDL :数据定义语言(Data Definition Language),用于创建数据库对象,如库、表、索等
DML :数据操纵语言(Data Manipulation Language),用于对表中的数据进行管理
DQL :数据查询语言(Data Query Language),用于从数据表中查找符合条件的数据记录
DCL :数据控制语言(Data Control Language),用于设置或者更改数据库用户或角色权限
2、查
①基础查法
(1)查看当前服务器中的数据库
show databases; #大小写不区分,分号“;”表示结束
(2)查看数据库中包含的表
use 数据库名; #切换到此数据库
show tables; #查看包含的表
(3)查看表的结构(字段)
use 数据库名;
describe [数据库名.]表名;
可缩写成:desc 表名;
(4)查看表的内容
select * from 表名;
②、查询指定数据记录
①select 字段名1,字段名2[,…] from 表名 [where 条件表达式];
select id,name,score from test1 where id=1;
select id,score,name from test1 where id=1;
select id,name,id from test1 where id=1;
按照指定顺序显示id等于2的行:
mysql> select id,name,score from test where id =1;
+----+----------+-------+
| id | name | score |
+----+----------+-------+
| 1 | zhangsan | 66.60 |
+----+----------+-------+
1 row in set (0.00 sec)
mysql> select score,name,id from test where id =1;
+-------+----------+----+
| score | name | id |
+-------+----------+----+
| 66.60 | zhangsan | 1 |
+-------+----------+----+
1 row in set (0.00 sec)
mysql> select id,name,id from test where id =1;
+----+----------+----+
| id | name | id |
+----+----------+----+
| 1 | zhangsan | 1 |
+----+----------+----+
1 row in set (0.00 sec)
②以列表方式纵向显示:
select name from test\g
select name from test\G
mysql> select name from test\g
+----------+
| name |
+----------+
| zhangsan |
| lisi |
+----------+
2 rows in set (0.00 sec)
mysql> select name from test\G
*************************** 1. row ***************************
name: zhangsan
*************************** 2. row ***************************
name: lisi
③只显示前n行
select * from test limit n;
mysql> select*from test limit 2; #只显示前2行
+----+----------+-------+-------------------------------------------+
| id | name | score | passwd |
+----+----------+-------+-------------------------------------------+
| 1 | zhangsan | 66.60 | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 |
| 2 | lisi | 77.77 | 666123 |
+----+----------+-------+-------------------------------------------+
2 rows in set (0.00 sec)
④显示第n行后的前m行
select * from test1 limit 1,2;
mysql> select*from test; #我又添加了一行数据,
+----+----------+--------+-------------------------------------------+
| id | name | score | passwd |
+----+----------+--------+-------------------------------------------+
| 1 | zhangsan | 66.60 | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 |
| 2 | lisi | 77.77 | 666123 |
| 3 | luoxiang | 100.00 | 666 |
+----+----------+--------+-------------------------------------------+
3 rows in set (0.00 sec)
mysql> select*from test limit 1,2;
+----+----------+--------+--------+
| id | name | score | passwd |
+----+----------+--------+--------+
| 2 | lisi | 77.77 | 666123 |
| 3 | luoxiang | 100.00 | 666 |
+----+----------+--------+--------+
2 rows in set (0.00 sec)
3、增
(1)创建新的数据库
create database 数据库名;
(2)创建新的表
create table 表名 (字段1 数据类型,字段2 数据类型[,…][,parmary key (主键名)]);
主键一般选择能代表唯一性的字段,不允许取空值(NULL),一个表只能有一个主键。
例:
mysql> create database qiao; #创建qiao数据库
mysql> use qiao;
#创建一个表,字段id为int类型,不可为空,字段name为char类型,不可为空,字段score为decimal类型,5个有效长度,小数点后面取2位,id字段设置为主键。
mysql> CREATE TABLE test (id int NOT NULL,name char(10) NOT NULL,score decimal(5,2),passwd char(48) DEFAULT '',PRIMARY KEY (id));
desc test1;
mysql> desc test;
+--------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+--------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | char(10) | NO | | NULL | |
| score | decimal(5,2) | YES | | NULL | |
| passwd | char(48) | YES | | | |
+--------+--------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
4、删
1、删除指定的数据表
drop table 数据库.表名; #如不用use进入库中,只需加上数据库名
2、删除指定的数据库
drop database 数据库名;
3、在数据表中删除指定的数据记录
delect from 表名 [where 条件表达式];
例:
delete from test1 where id=2;
mysql> select*from test;
+----+----------+--------+-------------------------------------------+
| id | name | score | passwd |
+----+----------+--------+-------------------------------------------+
| 1 | zhangsan | 66.60 | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 |
| 3 | luoxiang | 100.00 | 666 |
+----+----------+--------+-------------------------------------------+
2 rows in set (0.00 sec)
4、删除字段
alter table 表名 drop 字段名;
例:
mysql> desc giao;
+-----------+--------------+------+-----+--------------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+--------------+-------+
| id | int(11) | NO | PRI | NULL | |
| user_name | varchar(10) | YES | UNI | NULL | |
| score | decimal(5,2) | YES | | NULL | |
| passwd | char(48) | YES | | | |
| address | varchar(50) | YES | | 地址不详 | |
+-----------+--------------+------+-----+--------------+-------+
5 rows in set (0.00 sec)
mysql> alter table giao drop score;
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc giao;
+-----------+-------------+------+-----+--------------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+--------------+-------+
| id | int(11) | NO | PRI | NULL | |
| user_name | varchar(10) | YES | UNI | NULL | |
| passwd | char(48) | YES | | | |
| address | varchar(50) | YES | | 地址不详 | |
+-----------+------------
5、改
1、向数据表中插入新的数据记录
方法一:
insert into 表名(字段1,字段2[,…]) values(1,‘zhangsan’,70.5,PASSWORD(‘123456’));
PASSWORD(‘123456’):查询数据记录时,密码字串以加密形式显示,若不使用PASSWORD(),查询时以明文显示
mysql> insert into test(id,name,score,passwd) values(1,'zhangsan',66.6,password('123456'));
mysql> select * from test;
+----+----------+-------+-------------------------------------------+
| id | name | score | passwd |
+----+----------+-------+-------------------------------------------+
| 1 | zhangsan | 66.60 | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 |
+----+----------+-------+-------------------------------------------+
1 row in set (0.00 sec)
方法二:
mysql> insert into test values(2,'lisi',77.77,666123);
Query OK, 1 row affected (0.00 sec)
mysql> select*from test; #查看表内容
+----+----------+-------+-------------------------------------------+
| id | name | score | passwd |
+----+----------+-------+-------------------------------------------+
| 1 | zhangsan | 66.60 | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 |
| 2 | lisi | 77.77 | 666123 |
+----+----------+-------+-------------------------------------------+
2 rows in set (0.00 sec)
2、修改、更新数据表中的数据记录
update 表名 set 字段1=字段值1[,字段2=字段值2,...] [where 条件表达式];
例:
mysql> update test set score='99' where id=2;
mysql> select*from test;
+----+----------+--------+-------------------------------------------+
| id | name | score | passwd |
+----+----------+--------+-------------------------------------------+
| 1 | zhangsan | 66.60 | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 |
| 2 | lisi | 99.00 | 666123 |
| 3 | luoxiang | 100.00 | 666 |
+----+----------+--------+-------------------------------------------+
3 rows in set (0.00 sec)
3、修改表名和表结构
1、修改表名
alter table 旧表名 rename 新表名;
例:
mysql> alter table test rename giao;
mysql> show tables;
+----------------+
| Tables_in_qiao |
+----------------+
| giao |
+----------------+
1 row in set (0.00 sec)
2、扩展表结构(增加字段)
alter table 表名 ADD address varchar(50) default ‘地址不详’;
deafult ‘地址不详’:表示此字段设置默认值“地址不详”,可与NOT NULL配合使用
例:
mysql> alter table giao add address varchar(50) default '地址不详'; #添加address字段,不写则默认为地址不详,
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> select*from giao;
+----+----------+--------+-------------------------------------------+--------------+
| id | name | score | passwd | address |
+----+----------+--------+-------------------------------------------+--------------+
| 1 | zhangsan | 66.60 | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | 地址不详 |
| 3 | luoxiang | 100.00 | 666 | 地址不详 |
+----+----------+--------+-------------------------------------------+--------------+
2 rows in set (0.00 sec)
4、修改字段(列)名,添加唯一键
alter table 表名 change 旧列名 新列名 数据类型 [unique key];
change可修改字段名、数据类型、约束等所有项
例如:
mysql> alter table giao change name user_name varchar(10) unique key;
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> desc giao;
+-----------+--------------+------+-----+--------------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+--------------+-------+
| id | int(11) | NO | PRI | NULL | |
| user_name | varchar(10) | YES | UNI | NULL | |
| score | decimal(5,2) | YES | | NULL | |
| passwd | char(48) | YES | | | |
| address | varchar(50) | YES | | 地址不详 | |
+-----------+--------------+------+-----+--------------+-------+
5 rows in set (0.00 sec)
6、案例扩展
use test;
create table if not exists info (
id int(4) zerofill primary key auto_increment,
name varchar(10) not null,
cardid int(18) not null unique key,
hobby varchar(50));
mysql> create table if not exists info (
-> id int(4) zerofill primary key auto_increment,
-> name varchar(10) not null,
-> cardid int(18) not null unique key,
-> hobby varchar(50));
Query OK, 0 rows affected (0.00 sec)
mysql> desc info;
+--------+--------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+--------------------------+------+-----+---------+----------------+
| id | int(4) unsigned zerofill | NO | PRI | NULL | auto_increment |
| name | varchar(10) | NO | | NULL | |
| cardid | int(18) | NO | UNI | NULL | |
| hobby | varchar(50) | YES | | NULL | |
+--------+--------------------------+------+-----+---------+----------------+
4 rows in set (0.01 sec)
if on exists:表示检测要创建的表是否已存在,如果不存在就继续创建
int(4) zerofill:表示若数制不满4位数,则前面用“0”填充,例如0001
auto_increment:表示此字段为自增长字段,即每条记录自动递增1,默认从1开始递增;增长字段数据不可以重复;自增长字段必须是主键;如添加的记录数据没有指定此字段的值且添加失败也会自动递增一次
unique key:表示此字段唯一键约束,此字段数据不可以重复,一张表中只能有一个主键,但是可以多多个唯一键
not null:表示此字段不允许为null