上篇文章,我们基于『数据库』做了一个宏观上的介绍,你应当了解到数据库是在何种背景下,为了解决什么样的问题而诞生的,以及在具体实现下又可以划分哪些中类型。
非关系型数据库的种类很多,我们会在后续的篇章中进行介绍,数据库这块我们还是以目前当下主流的关系型数据库进行学习。
SQL 是什么
我们看看
SQL(结构化查询语言)是一种特定目的编程语言,用于管理关系数据库管理系统(RDBMS),或在关系流数据管理系统(RDSMS)中进行流处理
简而言之,SQL 是一门编程语言,它很特殊,它是一门帮助我们管理数据的标准语言。
为什么强调标准语言?
关系型数据的主要三大实现者分别是,Mysql,MS SQLServer,Oracle。
它们实现数据存储的底层引擎或许不同,但提供出来管理数据的编程语言必须遵循 SQL 规范,但可以定制添加属于自己的额外语法,这些额外的、SQL 之外的语法又被称作它们各自的『SQL方言』。
记得遇到过很多新手,拿着 SqlServer 的方言跑到 Mysql 里去执行,怎么都报错,怎么都解决不了。其实还是没了解到这一层。
数据库管理
一个数据库系统里是可以同时存在多个数据库的,也就是说一个数据库引擎可以服务多个数据库。
当你成功登陆数据库系统之后,你可以通过这么一个命令查看系统中存在的数据库集合。
SHOW DATABASES;
除此之外,你也可以创建数据库,使用以下这个命令。
CREATE DATABASE [DATABASENAEM];
如果你想要删除某个数据库:
DROP DATABASE [DATABASENAEM];
如果你需要选中某个数据库,这里说明一下,数据库由多张数据表构成,如果你想要操作数据表,你就必须先选中某个数据库,不然系统怎么知道你这一顿猛如虎的操作是基于的哪个数据库下的表呢。
USE[DATABASENAEM];
数据库的管理其实没什么太复杂的,它就像一个容器一样,创建后就意味着占有了一块磁盘空间,具体的数据存储还是在表结构中,所以接下来我们来看看数据库表管理情况。
表管理
关系型数据库中对于数据的存储采用一种符合人的思维逻辑的结构进行存储,那就是表格结构。
表格是一个二维的结构,有行和列,我们管一行数据叫做『一条记录』或是『一条数据』,每一列都是一条数据的一部分,我们管某一列的数据叫做『字段』,在数据库中它们可以具有不同的数据类型。
SQL 规范了以下一些通用的数据类型:
但是实际上,SQLServer,Oracle,MySQL 等数据库的具体实现上也大多都支持这些类型,只不过在不同的数据库中,同一种数据类型可能有不同的名称。
举个例子吧,数据类型 Integer,在 Oracle 里使用 Number 描述,SQLServer 里使用 int 来描述,而 MySQL 里既可以使用 int 也可以使用 Integer 进行描述。
所以,在我看来,既然大家都不是那么遵守规范,那么就没必要谨记规范,你用到哪个数据库,你去了解他的数据类型就是了。
我以 MySQL 来说,他主要的数据类型大致可以分为三类,Text(文本)、Number(数字)和 Date/Time(日期/时间)。
==Text 类型:==
==Number 类型:==
==Date 类型:==
有了数据类型,我们的列也就有了类型约束了,也即限定了每一列该存放什么类型的数据,那么我们的表结构也就由此确定了。
现在我们来看看如何在一个数据库中创建一张表:
CREATE TABLE table_name(
column1 datatype,
column2 datatype,
column3 datatype,
.....
columnN datatype
);
复制代码
这是最基本的创建表语句,例如我们可以这样创建一张表:
CREATE TABLE person(
id int,
name varchar(16),
phone char(11),
);
复制代码
当然,这种方式创建的表结构还是太简单了,现实中我们的字段往往具有更加严格的约束。
1、NULL 非空约束
NULL 约束用来指定当前字段的值是否允许为空,这里的空并不是空字符串,空格字符串,而是未对该字段赋值就判定为空。
create table person(
id,int NOT NULL,
uName,varchar(16) NOT NULL,
phone,char(11) NUll
)
复制代码
NULL 则指定该字段的值可以为空,NOT NULL 指定该字段不可以为空。
2、DEFAULT 默认约束
DEFAULT 约束用于指定某一列在允许为 NULL 的前提下,如果在插入数据时未赋值该字段时,数据库统一赋的默认值。
create table person(
id int DEFAULT 12,
uName VARCHAR(16)
)
复制代码
当我们向表 person 插入数据时,如果你不为 id 字段赋值,那么该条数据记录的 id 值就会是 12 。
3、UNIQUE 唯一约束
UNIQUE 约束用于限制表的某一字段不可重复,也即唯一,一张表中可以有很多记录,每条记录的该字段的值必须各不相同。
create table person(
id int,
uName VARCHAR(16) UNIQUE
)
复制代码
这样,无论你向 person 表中插入多少条数据记录,uName 这个字段的是必须各不相同,也即当你尝试向 person 表插入一条数据时,如果检测到你将要插入的这条数据的 uName 字段的值在表中已知记录中存在,你将不能成功插入。
4、PRIMARY KEY 主键约束
『主键』就是能够唯一确定一条具体数据记录的一个或多个字段的组合,也就是说,主键是表数据中一行记录的标记,通过它可以唯一定位到一行数据记录。
它与我们的 UNIQUE 看起来是一样的,我们可以通过 UNIQUE 指定表的一个或多个字段唯一不可重复,看似 UNIQUE 也可以唯一确定一行数据?
但时,UNIQUE 是不能唯一确定一行数据的,那是因为 UNIQUE 对空值无法约束。
你不让我将字段的值赋值为表中已知行数据的该字段值,那我可以不赋值,该字段的值为空。
所以,存在一种情况就是,已经对表的某一字段进行了 UNIQUE 约束,但时表中大量行数据的该字段值为空,你还能通过该字段唯一确定一行吗?
有人认为我们的主键约束就等同于 UNIQUE + NOT NULL 两个约束的集合,但其实我认为这并不准确,因为有时我们的主键可以由多个字段共同构成,只要他们组合起来能够唯一确定一行数据,单个字段是否遵守上述两个约束就成为非必要条件了。
例如:我有一张 person 表,里面保存了很多数据,已知可以通过姓名的手机号码唯一确定一条数据,那么我们的主键就是姓名和手机号码两个字段的组合,而至于姓名是否唯一,是否允许为空,我们不需要关心。
这其实就是主键约束和 UNIQUE 约束的一个主要的区别所在,你只要记住主键是用于唯一确定一行数据的,UNIQUE 用于约束某一字段的值不可重复出现。
关于主键约束的语法,
create table person(
id int primary key,
uName varchar(16)
)
复制代码
如果需要多个字段组合构成主键,语法是这样的:
create table person(
id int,
uName varchar(16),
primary key(id,uName)
)
复制代码
5、FOREIGN KEY 约束
最后我们讲讲外键约束,关系型数据库的一个核心特点就是表与表之间可以存在关系,而如何关联到另外一张表呢?这就用到一个键叫『外键』,两张表之间的微妙关系我们可以叫做外键约束。
举个例子吧,自己画图太丑,网上随便找的表结构示意图:
这里涉及到两张表,第一张订单表记录交易记录数据,其中也需要记录下创建这笔订单的消费者,一种做法是把 persons 表中的所有字段重新定义一遍,追加到 Orders 表中,这显然繁琐、字段冗余。
另一种做法就是我只增加一个字段,该字段存储的值是 persons 表的主键,也就是当我需要关联到某一个具体的 person 时,我只保存它的主键值,而不去保存它所有的字段信息,因为我是可以通过主键值定位到 persons 表的某条具体数据的。
上述示例中,我们管订单表中的 Id_P 字段叫做『外键』,它其实又是 persons 表的『主键』。
因此,构建一个外键约束,可以使用如下语法:
CREATE TABLE Orders
(
Id_O int NOT NULL,
OrderNo int NOT NULL,
Id_P int,
PRIMARY KEY (Id_O),
FOREIGN KEY (Id_P) REFERENCES Persons(Id_P)
)
复制代码
前提是,Persons 表已经存在,否则将创建 Orders 表失败。
以上,我们讲了创建表所涉及到的一些基本的内容,包括基本的字段类型、约束限制等,
但有的时候,表结构已经创建出来了,由于一些需求变更需要更改表结构,我们总不能 drop table 再重新定义一遍吧,SQL 规范中也提供了动态修改表结构的语句语法,我们一起来看看:
1、为表新增列
ALTER TABLE [tableName] ADD [columName] [列数据类型]
复制代码
例如:
alter table person add email varchar(24)
复制代码
为 person 表新增一列 email,varchar 类型。
2、修改表列属性
列属性包括,列名、列数据类型,我们分别来看下修改它们的 SQL 语法。
修改列名:
alter table 表名 change column 旧列名 新列名 新列名格式;
复制代码
例如:
alter table person change column uName userName varchar(123)
复制代码
修改列数据类型:
MySQL:
alter table 表名 modify column 列名 列类型
复制代码
例如:
alter table person modify column userName varchar(16)
复制代码
SQLServer:
alter table 表名 alter column 列名 列类型
复制代码
修改数据类型这块,各个应用数据库实现语法稍有差异,但仅限于关键字不同,格式上大体相似。
3、删除列
alter table 表名 drop column 列名
复制代码
例如:
ALTER TABLE person DROP COLUMN email
复制代码
删除 person 表列 email。
关于表的删除,就更加简单了:
drop table 表名
复制代码
注意,这里的表删除是连同表结构加表数据全部删除,谨慎使用。
关于表管理,大体上就介绍到这,看似很多,但实际上并没有什么特别复杂的点,无非是创建、删除、修改表。
创建表的时候可以同时指定约束,修改表结构又分为修改列名和修改列的数据类型,而同时我们要小心谨慎使用 drop 删除表。
虽然本篇写很多,但并未涉及到复杂的 SQL 语句,仅限于简单的创建 DDL 语句,下一篇我们看较为复杂的 DML 语句,进一步了解 SQL 对表的增删改查。