第二章 数据类型和操作数据表

本章介绍一些常用的数据类型以及如何操作数据表。

1. 数据类型

1)定义:

数据类型是指列、存储过程参数、表达式和局部变量的数据特征,它决定了数据的存储格式,代表了不同的信息类型。

2)整型

五种整形数据类型:
TINYINT(一个字节) 有符号值: -128 – 127 无符号值:0 – 255
SMALLINT(两个字节) 有符号值: -32768 – 32767 无符号值:0 – 65536
MEDIUMINT(三个字节) 有符号值: -8388608 – 8388607 无符号值:0 – 16777215
INT(四个字节) 更大
BIGINT(八个字节) 最大
数据库的优化第一步是要选择合适的数据类型,避免不必要的浪费

3)浮点型

FLOAT[(M,D)]: 单精度浮点型
DOUBLE[(M,D)]: 双精度浮点型
M是数字总位数,D是小数位数。

4)日期时间型

DATE: 支持1000年1月1号——9999年12月31号。
DATETIME: 支持1000年1月1号0点——9999年12月31号23点59分59秒。
TIMESTAMP(时间戳): 1970年1月1号0点——2037年。
考虑到跨时区的问题,很多时候采用数字取代日期时间类型。

5) 字符型

CHAR(M):定长类型,数据不足指定字节数,补空格; M表示字节数
VARCHAR(M):变长类型,数据的字节就是存储的字节; M表示最大的字节数
ENUM(‘value1’,;value2’,…..)枚举值,集合中只能选一个;
SET(‘value1’,;value2’,…..)集合,在集合中做任意的排列组合,可以选一个值,也可以两个或更多。
还有一些:TINYTEXT,TEXY,MEDIUMTEXT.LONGTEXT

2.数据表

1)定义

数据表(或称表)是数据库最重要的组成部分之一,是其它对象的基础。

下面我们来创建一个数据表:

1)打开数据库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
C:\Windows\system32>net start mysql
MySQL 服务正在启动 .
MySQL 服务已经启动成功。


C:\Windows\system32>mysql -uroot -p
Enter password: ****
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.5.62 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

2)首先看一下有哪些数据库

1
2
3
4
5
6
7
8
9
10
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| t1 |
| test |
+--------------------+

3)下面我们在test数据库中创建数据表,首先打开test数据库

1
2
mysql> USE test;
Database changed

怎么证明当前数据库就是我们打开的test数据库呢?
有一个简单的方法:

1
2
3
4
5
6
mysql> SELECT DATABASE();
+------------+
| DATABASE() |
+------------+
| test |
+------------+

4)创建数据表

创建数据表:
CREATE TABLE [IF NOT EXISTC] table_name(
column_name data_type, //colum_namhe是列名称,data_type是数据类型
…如://username VARCHAR(20),20指长度
//age TINYINT UNSIGNED(意思是无负数,从0开始),
);
注意在数据库中 CREATE TABLE 是必须要有的;而[IF NOT EXISTC]
是表示可加可不加,如果数据表已创建且再加上[IF NOT EXISTS]再创建
系统不会报错

1
2
3
4
5
6
mysql> CREATE TABLE  tb1(
-> username VARCHAR(20),
-> age TINYINT UNSIGNED,
-> salary FLOAT(8,2) UNSIGNED
-> );
Query OK, 0 rows affected (0.04 sec)

此表只是演示,不具备实际意义。

5) 验证数据表是否真实存在

1
2
3
4
5
6
7
8
SHOW TABLES ;
mysql> SHOW TABLES;
+----------------+
| Tables_in_test |
+----------------+
| tb1 |
+----------------+
1 row in set (0.00 sec)

可以看出tb1已经存在。
当然我们不仅可以查看当前数据库中的列表,还可以查看其它数据库的列表,比如我们查看MySQL中的全部数据表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
mysql> SHOW TABLES FROM mysql;
+---------------------------+
| Tables_in_mysql |
+---------------------------+
| columns_priv |
| db |
| event |
| func |
| general_log |
| help_category |
| help_keyword |
| help_relation |
| help_topic |
| host |
| ndb_binlog_index |
| plugin |
| proc |
| procs_priv |
| proxies_priv |
| servers |
| slow_log |
| tables_priv |
| time_zone |
| time_zone_leap_second |
| time_zone_name |
| time_zone_transition |
| time_zone_transition_type |
| user |
+---------------------------+
24 rows in set (0.03 sec)

一共存在24个。
刚刚我们FROM某个库查看数据表,那当前数据库会不会发生改变吗?
我们再来验证一下:

1
2
3
4
5
6
7
mysql> SELECT DATABASE();
+------------+
| DATABASE() |
+------------+
| test |
+------------+
1 row in set (0.00 sec)

可以看出仍然是test数据库。

6)查看数据表的结构

刚刚已经验证数据表已经创建成功了,那么它的数据结构是我们所创建的吗?答案毋庸置疑,如果不放心,我们可以通过以下方式验证:
SHOW TABLES FROM tb1_name
此为查看数据表的列结构

1
2
3
4
5
6
7
8
9
mysql> SHOW COLUMNS FROM tb1;
+----------+---------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------------------+------+-----+---------+-------+
| username | varchar(20) | YES | | NULL | |
| age | tinyint(3) unsigned | YES | | NULL | |
| salary | float(8,2) unsigned | YES | | NULL | |
+----------+---------------------+------+-----+---------+-------+
3 rows in set (0.01 sec)

7)插入记录

既然数据表已经创建好啦,也就是列已经规定好,它可以有很多不固定的行(通过下面列子可以理解这里的行与列),行称之为记录,那么接下来我们写入记录。
INSERT [INTO] tb1_name [(col_name,…)] VALUES(val,…)
tbl_name 表的名字 省略[(col_name,…)]
INSERT 表名 VALUES (‘名字’,年龄,工资);

1
2
mysql> INSERT tb1 VALUES('xiaoming',18,12342.21);
Query OK, 1 row affected (0.00 sec)

如果少输入一组数据会怎么样呢?

1
2
mysql> INSERT tb1 VALUES('xiaohua',12342.21);
ERROR 1136 (21S01): Column count doesn't match value count at row 1

INSERT [INTO] tbl_name [(列名1,列名2)]VALUES(赋值,赋值);给特需位置赋值

1
2
mysql> INSERT tb1 (username,salary)VALUES('xiaogou',321.12);
Query OK, 1 row affected (0.03 sec)

8)查看记录

SELECT expr,… FORM ta1_name
SELECT 真实的用法很复杂,这里简单的使用一下,后面会有系统的介绍。

1
2
3
4
5
6
7
8
mysql> SELECT * FROM tb1;
+----------+------+----------+
| username | age | salary |
+----------+------+----------+
| xiaoming | 18 | 12342.21 |
| xiaogou | NULL | 321.12 |
+----------+------+----------+
2 rows in set (0.00 sec)

xiaogou的age我们没有设置,因此为NULL。

9)空值与非空

我们在网站填写表格时,经常会遇到,此项必填的情况,那么在数据表中我们应该怎么设置呢?
设置字段(标签)的属性:空值与非空
NULL, 字段值可以为空
NOT NULL,字段值禁止为空
使用方式:
CREATE TABEL tb1(
username VARCHAR(20) NOT NULL,
);
接下来我们再创建一个数据表,加入空值与非空的控制。

1
2
3
4
5
mysql> CREATE TABLE tb2(
-> name VARCHAR(20) NOT NULL,
-> age TINYINT UNSIGNED NULL
-> );
Query OK, 0 rows affected (0.01 sec)

验证一下:

1
2
3
4
5
6
7
8
mysql> SHOW COLUMNS FROM tb2;
+-------+---------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------------------+------+-----+---------+-------+
| name | varchar(20) | NO | | NULL | |
| age | tinyint(3) unsigned | YES | | NULL | |
+-------+---------------------+------+-----+---------+-------+
2 rows in set (0.04 sec)

可以看到name的Null为NO,age的Null为YES
接下来,插入记录:

1
2
mysql> INSERT tb2 VALUES('xiaohua',18);
Query OK, 1 row affected (0.03 sec)

当年龄为NULL时:

1
2
mysql> INSERT tb2 VALUES('xiaoxiao',NULL);
Query OK, 1 row affected (0.03 sec)

当name为NULL时:

1
2
mysql> INSERT tb2 VALUES(NULL,18);
ERROR 1048 (23000): Column 'name' cannot be null

出现错误,name不能为null。

10)自动编号

在记录时,我们需要保证记录的唯一性,即在数据表中这条记录不存在重复。此时我们可以通过添加AUTO_INCREAMENT属性来实现自动编号。
AUTO_INCREAMENT自动编号,且必须与主键组合使用;
默认情况下,起始值为1,每次的增量为1。

1
2
3
4
5
mysql> CREATE TABLE tb3(
-> id SMALLINT UNSIGNED AUTO_INCREMENT,
-> username VARCHAR(30) NOT NULL
-> );
ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key

出现错误there can be only one auto column and it must be defined as a key,所以我们必须要了解主键。

11)主键 PRIMARY KEY

主键约束
每张表只能存在一个主键
主键保证记录的唯一性
主键自动为NOT NULL
要注意AUTO_INCREAMENT必须与主键一起使用。

下面我们重新创建一个数据表:

1
2
3
4
5
mysql> CREATE TABLE tb3(
-> id SMALLINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
-> username VARCHAR(30) NOT NULL
-> );
Query OK, 0 rows affected (0.04 sec)

查看一下这个数据表:

1
2
3
4
5
6
7
8
mysql> SHOW COLUMNS FROM tb3;
+----------+----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+----------------------+------+-----+---------+----------------+
| id | smallint(5) unsigned | NO | PRI | NULL | auto_increment |
| username | varchar(30) | NO | | NULL | |
+----------+----------------------+------+-----+---------+----------------+
2 rows in set (0.04 sec)

可以看到id自动为NO NULL。KEY为PRIMARY

插入多条记录

1
2
3
4
5
6
7
8
mysql> INSERT tb3(username) VALUES('hua');
Query OK, 1 row affected (0.03 sec)

mysql> INSERT tb3(username) VALUES('hui');
Query OK, 1 row affected (0.03 sec)

mysql> INSERT tb3(username) VALUES('hao');
Query OK, 1 row affected (0.03 sec)

因为我们是为部分值赋值,所以不能省略(username)

检查是否自动编号

1
2
3
4
5
6
7
8
9
mysql> SELECT * FROM tb3;
+----+----------+
| id | username |
+----+----------+
| 1 | hua |
| 2 | hui |
| 3 | hao |
+----+----------+
3 rows in set (0.00 sec)

保证了记录的唯一性。

一开始我们提到AUTO_INCREAMENT必须与主键一起使用,那么主键是否必须与AUTO_INCREAMENT一起使用呢?下面验证一下吧!
再创建一个数据表

1
2
3
4
5
mysql> CREATE TABLE tb4(
-> id SMALLINT PRIMARY KEY,
-> username VARCHAR(20) NOT NULL
-> );
Query OK, 0 rows affected (0.03 sec)

注意id没有加入自动编码。
插入几条记录

1
2
3
4
5
6
7
8
mysql> INSERT tb4 VALUES(1,'chun');
Query OK, 1 row affected (0.03 sec)

mysql> INSERT tb4 VALUES(25,'xiao');
Query OK, 1 row affected (0.03 sec)

mysql> INSERT tb4 VALUES(18,'yue');
Query OK, 1 row affected (0.03 sec)

查看记录

1
2
3
4
5
6
7
8
9
mysql> SELECT * FROM tb4;
+----+----------+
| id | username |
+----+----------+
| 1 | chun |
| 18 | yue |
| 25 | xiao |
+----+----------+
3 rows in set (0.00 sec)

可以插入相同的id吗?

1
2
mysql> INSERT tb4 VALUES(18,'ye');
ERROR 1062 (23000): Duplicate entry '18' for key 'PRIMARY'

提示错误:不能多次插入18
因此AUTO_INCREAMENT必须与主键一起使用,主键可以不与AUTO_INCREAMENT一起使用。

12)唯一约束 UNIQUE KEY

  1. 另一个保证记录唯一性的方法:唯一约束。
  2. 唯一约束可以保证记录的唯一性
  3. 唯一约束的字段可以为空值(NULL)
  4. 每张数据表可以存在多个唯一约束

下面创建一个既有主键约束又有唯一约束的数据表

1
2
3
4
5
6
mysql> CREATE TABLE tb5(
-> id SMALLINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
-> username VARCHAR(20) NOT NULL UNIQUE KEY,
-> age TINYINT UNSIGNED
-> );
Query OK, 0 rows affected (0.04 sec)

查看数据表结构

1
2
3
4
5
6
7
8
9
mysql> SHOW COLUMNS FROM tb5;
+----------+----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+----------------------+------+-----+---------+----------------+
| id | smallint(5) unsigned | NO | PRI | NULL | auto_increment |
| username | varchar(20) | NO | UNI | NULL | |
| age | tinyint(3) unsigned | YES | | NULL | |
+----------+----------------------+------+-----+---------+----------------+
3 rows in set (0.04 sec)

id为主键约束,username为唯一约束。
添加记录

1
2
3
4
5
6
7
8
mysql> INSERT tb5(username,age) VALUES('hua',18);
Query OK, 1 row affected (0.03 sec)

mysql> INSERT tb5(username,age) VALUES('hua',18);
ERROR 1062 (23000): Duplicate entry 'hua' for key 'username'

mysql> INSERT tb5(username,age) VALUES('hao',18);
Query OK, 1 row affected (0.00 sec)

当插入第二个‘hua’时,出现错误提示,这就是唯一约束。

13)默认约束 DEFAULT

当插入记录时,如果没有明确为字段赋值,则自动赋予默认值。
首先还是创建一个数据表

1
2
3
4
5
6
mysql> CREATE TABLE tb6(
-> id SMALLINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
-> username VARCHAR(20) NOT NULL UNIQUE KEY,
-> sex ENUM('1','2','3') DEFAULT '3'
-> );
Query OK, 0 rows affected (0.04 sec)

再查看一下结构

1
2
3
4
5
6
7
8
9
mysql> SHOW COLUMNS FROM tb6;
+----------+----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+----------------------+------+-----+---------+----------------+
| id | smallint(5) unsigned | NO | PRI | NULL | auto_increment |
| username | varchar(20) | NO | UNI | NULL | |
| sex | enum('1','2','3') | YES | | 3 | |
+----------+----------------------+------+-----+---------+----------------+
3 rows in set (0.04 sec)

sex(性别)可以为NULL,‘1’表示男,‘2’表示女,‘3’表示保密。(不要想歪)
加入一条记录

1
2
mysql> INSERT tb6 (username) VALUES ('hui');
Query OK, 1 row affected (0.00 sec)

查看一下记录

1
2
3
4
5
6
7
mysql> SELECT * FROM tb6;
+----+----------+------+
| id | username | sex |
+----+----------+------+
| 1 | hui | 3 |
+----+----------+------+
1 row in set (0.00 sec)

sex在不赋值的情况下,默认为3。

小结:

数据类型
整型:tinyint; smallint; int
字符型:varchar(); char()
浮点型:float(m,n); double(m,n)
日期时间型
数据表操作
创建表create table tablename,
查看数据库中的表show tables from dataname,
查看表的属性字段show columus from tablename,
插入记录insert tablename (字段) values (值),
查询表的记录select * from tablename
字段属性
主键:主键的记录是唯一的,不能为空。一张表中只能有一个字段是主键。aout_increment:自动编号,从1开始,每次增加1,只能是主键。
唯一约束:记录的值是唯一的,可以为空。一张表中可以有多个字段是唯一约束。
默认约束:当插入记录时,没有明确为字段赋值时,则自动赋默认值。