描述事物的符号记录
包括数字、文字、图形、图像、声音、档案记录等
以“记录”形式按统一的格式进行存储
将不同的记录组织在一起
用来存储具体数据
表的集合,是存储数据的仓库
以一定的组织方式存储的相互有关的数据集合
是按照数据结构来组织、存储和管理数据的仓库
是实现对数据库资源有效组织、管理和存取的系统软件
● 数据库的建立和维护功能
● 数据定义功能
● 数据操作功能
● 数据库的运行管理功能
● 通信功能
是一个人机系统,由硬件、OS、数据库、DBMS、应用软件和数据库用户组成
用户可以通过DBMS或应用程序操作数据库
自20世纪60年代起,第一代数据库系统问世
是层次模型与网状模型的数据库系统
为统一管理和共享数据提供了有力的支撑
20世纪70年代初,第二代数据库——关系数据库开始出现
20世纪80年代初,IBM公司的关系数据库系统DB2问世,开始逐步取代层次与网状模型的数据库,称为行业主流
到目前为止,关系数据库系统仍占领数据库应用的主流地位
自20世纪80年代开始,适应不同领域的新型数据库系统不断涌现
面向对象的数据库系统,实用性强、适用面广
20世纪90年代后期,形成了多种数据库系统共同支撑应用的局面
一些新的元素被添加进主流数据库系统中,例如Oracle支持的“关系-对象”数据库模型
面向Windows操作系统
简单、易用
面向所有主流平台
安全、完善,操作复杂
面向所有主流平台
大型、安全、完善
免费、开源、体积小
面向所有主流平台
免费、开源,功能强大
涵盖关系型、非关系型数据库服务
可靠性、扩展性、备份恢复
金融级分布式关系数据库
数据强一致、高可用、高性能、在线扩展、高度兼容SQL标准和主流关系数据库、低成本
关系数据库系统是基于关系模型的数据库系统
关系模型的数据结构使用简单易懂的二维数据表
关系模型可用简单的“实体-关系”(E-R)图来表示
E-R图中包含了实体(数据对象)、关系和属性三个要素
也称为实例,对应现实世界中可区别于其他对象的“事件”或“事务”
如上图的银行客户、银行账户
实体所具有的某一特性,一个实体可以有多个属性
如上图的“银行客户”实体集中的每个实体均具有姓名、住址、电话等属性
实体集之间的对应关系称为联系,也称为关系
如银行客户和银行账户之间存在“储蓄”的关系
所有实体及实体之间联系的集合构成了一个关系数据库
关系数据库的存储结构是二维表格
在每个二维表中
● 每一行称为一条记录,用来描述一个对象的信息
● 每一列称为一个字段,用来描述对象的一个属性
关系型数据库 | 应用举例 |
---|---|
Oracle、MySQL | 12306用户信息系统 |
SQL Server、Sybase | 淘宝账号系统 |
Informix、access | 联通手机号信息系统 |
DB2、FoxPRO | 银行用户账号系统 |
PostgreSQL | 网站用户信息系统 |
非关系数据库也被称为NoSQL(Not Only SQL)
存储数据不以关系模型为依据,不需要固定的表格式
常用的非关系数据库有:Redis、mongoDB等
● 数据库可高并发读写
● 对海量数据高效率存储与访问
● 数据库具有高扩展性与高可用性
优势:
● 成本:nosql数据库简单易部署,基本都是开源软件,不需要像使用oracle那样花费大量成本购买使用,相比关系型数据库价格便宜。
● 查询速度:nosql数据库将数据存储于缓存之中,关系型数据库将数据存储在硬盘中,自然查询速度远不及nosql数据库。
● 存储数据的格式:nosql的存储格式是key,value形式、文档形式、图片形式等等,所以可以存储基础类型以及对象或者是集合等各种格式,而数据库则只支持基础类型。
● 扩展性:关系型数据库有类似join这样的多表查询机制的限制导致扩展很艰难。
缺点:
● 维护的工具和资料有限,因为nosql是属于新的技术,不能和关系型数据库10几年的技术同日而语。
● 不提供对sql的支持,如果不支持sql这样的工业标准,将产生一定用户的学习和使用成本。
● 不提供关系型数据库对事物的处理。
数据存储结构
首先关系型数据库一般都有固定的表结构,并且需要通过DDL语句来修改表结构,不是很容易进行扩展,而非关系型数据库的存储机制就有很多了,比如基于文档的,K-V键值对的,还有基于图的等,对于数据的格式十分灵活没有固定的表结构,方便扩展,因此如果业务的数据结构并不是固定的或者经常变动比较大的,那么非关系型数据库是个好的选择
可扩展性
传统的关系型数据库给人一种横向扩展难,不好对数据进行分片等,而一些非关系型数据库则原生就支持数据的水平扩展(比如mongodb的sharding机制),并且这可能也是很多NoSQL的一大卖点,其实像Mysql这种关系型数据库的水平扩展也并不是难,即使NoSQL水平扩展容易但对于向跨分片进行joins这种场景都没有什么太好的解决办法,不管是关系型还是非关系型数据库,解决水平扩展或者跨分片Joins这种场景,在应用层和数据库层中间加一层中间件来做数据处理也许是个好的办法
数据一致性 非关系型数据库一般强调的是数据最终一致性,而不没有像ACID一样强调数据的强一致性,从非关系型数据库中读到的有可能还是处于一个中间态的数据,因此如果你的业务对于数据的一致性要求很高,那么非关系型数据库并不一个很好的选择,非关系型数据库可能更多的偏向于OLAP场景,而关系型数据库更多偏向于OLTP场景
一款深受欢迎的开源关系型数据库
Oracle旗下的产品
遵守GPL协议,可以免费使用与修改
● 性能卓越、服务稳定
● 开源、无版权限制、成本低
● 多线程、多用户
● 基于C/S(客户端/服务器)架构
● 安全可靠
MySQL商业版是由MySQL AB公司负责开发与维护,需要付费才能使用
MySQL社区版是由分散在世界各地的MySQL开发者、爱好者一起开发与维护,可以免费使用
两者区别在于
● 商业版组织管理与测试环节更加严格,会比社区版更稳定
● 商业版不遵守GPL,社区版遵从GPL可以免费使用
● 商业版可获得7*24小时的服务,社区版则没有
第一阵营: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
MySQL主要包括以下五大类
● 整数类型:BIT、BOOL、TINY INT、SMALL INT、MEDIUM INT、 INT、 BIG INT
● 浮点数类型:FLOAT、DOUBLE、DECIMAL
● 字符串类型:CHAR、VARCHAR、TINY TEXT、TEXT、MEDIUM TEXT、LONGTEXT、TINY BLOB、BLOB、MEDIUM BLOB、LONG BLOB
● 日期类型:Date、DateTime、TimeStamp、Time、Year
● 其他数据类型:BINARY、VARBINARY、ENUM、SET、Geometry、Point、MultiPoint、LineString、MultiLineString、Polygon、GeometryCollection等
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次方) |
int(m)中的m不是限制字段取值范围的,int的取值范围是固定的(0至4294967295)或(-2147483648至2147483647),如果加了unsigned参数那么取值范围就为(0至4294967295),m这个值是为了zerofill在字段中的值不够时补零的
MySQL数据类型 | 含义 |
---|---|
float(m,d) | 单精度浮点型,8位精度(4字节),m总个数,d小数位 |
double(m,d) | 双精度浮点型,16位精度(8字节),m总个数,d小数位 |
设一个字段定义为float(6,3),如果插入一个数123.45678,实际数据库里存的是123.456,但总个数还以实际为准,即6位。整数部分最大是3位,如果插入数12.123456,存储的是12.1234,如果插入12.12,存储的是12.1200。
浮点型在数据库中存放的是近似值,而定点类型在数据库中存放的是精确值。
decimal(m,d) 参数m<65 是总个数,d<30且 d<m 是小数位。
MySQL数据类型 | 含义 |
---|---|
char(n) | 固定长度,最多255个字符 |
varchar(n) | 固定长度,最多65535个字符 |
tinytext | 可变长度,最多255个字符 |
text | 可变长度,最多65535个字符 |
mediumtext | 可变长度,最多2的24次方-1个字符 |
longtext | 可变长度,最多2的32次方-1个字符 |
char和varchar区别
● char(n) 若存入字符数小于n,则以空格补于其后,查询之时再将空格去掉。所以char类型存储的字符串末尾不能有空格,varchar不限于此。
● char(n) 固定长度,char(4)不管是存入几个字符,都将占用4个字节,varchar是存入的实际字符数+1个字节(n<=255)或2个字节(n>255),所以varchar(4),存入3个字符将占用4个字节。
● char类型的字符串检索速度要比varchar类型的快。
varchar和text区别
● varchar可指定n,text不能指定,内部存储varchar是存入的实际字符数+1个字节(n<=255)或2个字节(n>255),text是实际字符数+2个字节。
● text类型不能有默认值。
● varchar可直接创建索引,text创建索引要指定前多少个字符。varchar查询速度快于text,在都创建索引的情况下,text的索引似乎不起作用。
MySQL数据类型 | 含义 |
---|---|
date | 日期 '2008-12-2' |
time | 时间 '12:25:36' |
datetime | 日期时间 '2008-12-2 22:06:44' |
timestamp | 自动存储记录修改时间 |
若定义一个字段为timestamp,这个字段里的时间数据会随其他字段修改的时候自动刷新,所以这个数据类型的字段可以存放这条记录最后被修改的时间。
MySQL关键字 | 含义 |
---|---|
NULL | 数据列可包含NULL值 |
NOT NULL | 数据列不允许包含NULL值 |
DEFAULT | 默认值 |
PRIMARY KEY | 主键 |
UNIQUE KEY | 唯一约束 |
AUTO_INCREMENT | 自动递增,适用于整数类型 |
UNSIGNED | 无符号 |
CHARACTER SET name | 指定一个字符集 |
唯一约束(Unique Key)是指所有记录中字段的值不能重复出现。例如,为 id 字段加上唯一性约束后,每条记录的 id 值都是唯一的,不能出现重复的情况。如果其中一条记录的 id 值为‘0001’,那么该表中就不能出现另一条记录的 id 值也为‘0001’。
唯一约束与主键约束相似的是它们都可以确保列的唯一性。不同的是,唯一约束在一个表中可有多个,并且设置唯一约束的列允许有空值,但是只能有一个空值。而主键约束在一个表中只能有一个,且不允许有空值。比如,在用户信息表中,为了避免表中用户名重名,可以把用户名设置为唯一约束。
数据类型 | 字节长度 | 范围或用法 |
---|---|---|
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个不同的值 |
Geometry | ||
Point | ||
LineString | ||
Polygon | ||
MultiPoint | ||
MultiLineString | ||
MultiPolygon | ||
GeometryCollection |
SQL语句用于维护管理数据库,包括数据查询、数据更新、访问控制、对象管理等功能
SQL语言 | 说明 |
---|---|
DDL | 数据定义语言(Data Definition Language),用于创建数据库对象,如库、表、索引等 |
DML | 数据操纵语言(Data Manipulation Language),用于对表中的数据进行管理 |
DQL | 数据查询语言(Data Query Language),用于从数据表中查找符合条件的数据记录 |
DCL | 数据控制语言(Data Control Language),用于设置或者更改数据库用户或角色权限 |
show databases;
大小写不区分,分号“;”表示结束
use 数据库名;
show tables;
use 数据库名;
describe [数据库名.]表名;
可缩写成:desc 表名;
create database 数据库名;
create table 表名 (字段1 数据类型,字段2 数据类型[,...][,parmary key (主键名)]);
主键一般选择能代表唯一性的字段,不允许取空值(NULL),一个表只能有一个主键。
例如:
mysql> create database test; mysql> use test; mysql> CREATE TABLE test1 (id int NOT NULL,name char(10) NOT NULL,score decimal(5,2),passwd char(48) DEFAULT '',PRIMARY KEY (id)); desc test1; mysql> desc test1; +--------+--------------+------+-----+---------+-------+ | 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)
drop table [数据库名.]表名;
如不用use进入库中,则需加上数据库名
drop database 数据库名;
方法1:
insert into 表名(字段1,字段2[,...]) values(1,'zhangsan',70.5,PASSWORD('123456'));
PASSWORD('123456'):查询数据记录时,密码字串以加密形式显示,若不使用PASSWORD(),查询时以明文显示
mysql> insert into test1(id,name,score,passwd) values(1,'zhangsan',70.5,PASSWORD('123456'))); Query OK, 1 row affected, 1 warning (0.00 sec) mysql> select * from test1; +----+----------+-------+-------------------------------------------+ | id | name | score | passwd | +----+----------+-------+-------------------------------------------+ | 1 | zhangsan | 70.50 | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | +----+----------+-------+-------------------------------------------+ 1 row in set (0.00 sec)
方法2:
insert into 表名 values(2,'lisi',90,654321);
mysql> insert into test1 values(2,'lisi',90,654321); Query OK, 1 row affected (0.00 sec) mysql> select * from test1; +----+----------+-------+-------------------------------------------+ | id | name | score | passwd | +----+----------+-------+-------------------------------------------+ | 1 | zhangsan | 70.50 | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | | 2 | lisi | 90.00 | 654321 | +----+----------+-------+-------------------------------------------+ 2 rows in set (0.00 sec)
select 字段名1,字段名2[,...] from 表名 [where 条件表达式];
例如:
select * from test1;
查看完整表
mysql> select * from test1; +----+----------+-------+-------------------------------------------+ | id | name | score | passwd | +----+----------+-------+-------------------------------------------+ | 1 | zhangsan | 70.50 | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | | 2 | lisi | 90.00 | 654321 | +----+----------+-------+-------------------------------------------+ 2 rows in set (0.00 sec)
select id,name,score from test1 where id=2;
select id,score,name from test1 where id=2;
按照指定顺序显示id等于2的行
mysql> select id,name,score from test1 where id=2; +----+------+-------+ | id | name | score | +----+------+-------+ | 2 | lisi | 90.00 | +----+------+-------+ 1 row in set (0.00 sec) mysql> select id,score,name from test1 where id=2; +----+-------+------+ | id | score | name | +----+-------+------+ | 2 | 90.00 | lisi | +----+-------+------+ 1 row in set (0.00 sec)
mysql> select name from test1\G
以列表方式纵向显示
mysql> select name from test1\G *************************** 1. row *************************** name: zhangsan *************************** 2. row *************************** name: lisi 2 rows in set (0.00 sec)
select * from test1 limit 2;
只显示前2行
mysql> select * from test1 limit 2; +----+----------+-------+-------------------------------------------+ | id | name | score | passwd | +----+----------+-------+-------------------------------------------+ | 1 | zhangsan | 70.50 | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | | 2 | lisi | 90.00 | 654321 | +----+----------+-------+-------------------------------------------+ 2 rows in set (0.00 sec)
select * from test1 limit 2,3;
显示第2行后的前3行
mysql> select * from test1 limit 2,3; Empty set (0.00 sec)
update 表名 set 字段1=字段值1[,字段2=字段值2,...] [where 条件表达式];
例如:
update test1 set passwd=PASSWORD('') where name='zhangsan';
mysql> update test1 set passwd=PASSWORD('') where name='zhangsan'; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from test1; +----+----------+-------+--------+ | id | name | score | passwd | +----+----------+-------+--------+ | 1 | zhangsan | 70.50 | | | 2 | lisi | 90.00 | 654321 | +----+----------+-------+--------+ 2 rows in set (0.01 sec
update test1 set name='wangwu',passwd='' where id=2;
mysql> update test1 set name='wangwu',passwd='' where id=2; Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from test1; +----+----------+-------+--------+ | id | name | score | passwd | +----+----------+-------+--------+ | 1 | zhangsan | 70.50 | | | 2 | wangwu | 90.00 | | +----+----------+-------+--------+ 2 rows in set (0.00 sec)
delect from 表名 [where 条件表达式];
例如:
delete from test1 where id=2;
mysql> delete from test1 where id=2; Query OK, 1 row affected (0.00 sec) mysql> select * from test1; +----+----------+-------+--------+ | id | name | score | passwd | +----+----------+-------+--------+ | 1 | zhangsan | 70.50 | | +----+----------+-------+--------+ 1 row in set (0.00 sec)
alter table 旧表名 rename 新表名;
例如:
alter table test1 rename test_table1;
mysql> alter table test1 rename test_table1; Query OK, 0 rows affected (0.00 sec) mysql> show tables; +----------------+ | Tables_in_test | +----------------+ | test_table1 | +----------------+ 1 row in set (0.00 sec)
alter table 表名 ADD address varchar(50) default '地址不详';
deafult '地址不详':表示此字段设置默认值“地址不详”,可与NOT NULL配合使用
例如:
alter table test_table1 ADD address varchar(50) default '地址不详';
mysql> alter table test_table1 ADD address varchar(50) default '地址不详'; Query OK, 0 rows affected (0.08 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> select * from test_table1; +----+----------+-------+--------+--------------+ | id | name | score | passwd | address | +----+----------+-------+--------+--------------+ | 1 | zhangsan | 70.50 | | 地址不详 | +----+----------+-------+--------+--------------+ 1 row in set (0.00 sec)
alter table 表名 change 旧列名 新列名 数据类型 [unique key];
change可修改字段名、数据类型、约束等所有项
例如:
alter table test_table1 change name user_name varchar(10) unique key;
mysql> alter table test_table1 change name user_name varchar(10) unique key; Query OK, 1 row affected (0.01 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> desc test_table1; +-----------+--------------+------+-----+--------------+-------+ | 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)
alter table 表名 drop 字段名;
例如:
alter table test_table1 drop passwd;
mysql> alter table test_table1 drop passwd; Query OK, 0 rows affected (0.03 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> desc test_table1; +-----------+--------------+------+-----+--------------+-------+ | 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 | | | address | varchar(50) | YES | | 地址不详 | | +-----------+--------------+------+-----+--------------+-------+ 4 rows in set (0.00 sec)
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