第06天 MySQL数据库

今日内容介绍

u MySQL单表查询

u SQL约束

u 多表操作

第1章   MySQL单表查询

1.1  SQL单表查询--排序

1.1.1 排序格式

通过order by语句,可以将查询出的结果进行排序。放置在select语句的最后。

格式:

SELECT * FROM 表名 ORDER BY 排序字段 ASC|DESC;

ASC 升序 (默认)

DESC 降序

#1.使用价格排序(降序)

SELECT * FROM product ORDER BY price DESC;

#2.在价格排序(降序)的基础上,以分类排序(降序)

SELECT * FROM product ORDER BY price DESC,category_id DESC;

#3.显示商品的价格(去重复),并排序(降序)

SELECT DISTINCT price FROM product ORDER BY price DESC;

1.1.2 案例练习一

#排序

#1.1.使用价格排序(降序)

SELECT * FROM product ORDER BY price DESC;

#1.2.在价格排序(降序)的基础上,以分类排序(降序)

SELECT * FROM product ORDER BY price DESC,category_id DESC;

#1.3.显示商品的价格(去重复),并排序(降序)

SELECT DISTINCT price FROM product ORDER BY price DESC;

SELECT DISTINCT price FROM product ORDER BY price ASC;

SELECT DISTINCT price FROM product ORDER BY price;

1.2  SQL单表查询--聚合

之前我们做的查询都是横向查询,它们都是根据条件一行一行的进行判断,而使用聚合函数查询是纵向查询,它是对一列的值进行计算,然后返回一个单一的值;另外聚合函数会忽略空值。

今天我们学习如下五个聚合函数:

l  count:统计指定列不为NULL的记录行数;

l  sum:计算指定列的数值和,如果指定列类型不是数值类型,那么计算结果为0;

l  max:计算指定列的最大值,如果指定列是字符串类型,那么使用字符串排序运算;

l  min:计算指定列的最小值,如果指定列是字符串类型,那么使用字符串排序运算;

l  avg:计算指定列的平均值,如果指定列类型不是数值类型,那么计算结果为0;

1.2.1 案例练习二

#1 查询商品的总条数

SELECT COUNT(*) FROM product;

#2 查询价格大于200商品的总条数

SELECT COUNT(*) FROM product WHERE price > 200;

#3 查询分类为'c001'的所有商品的总和

SELECT SUM(price) FROM product WHERE category_id = 'c001';

#4 查询分类为'c002'所有商品的平均价格

SELECT AVG(price) FROM product WHERE category_id = 'c002';

#5 查询商品的最大价格和最小价格

SELECT MAX(price),MIN(price) FROM product;

1.3  SQL单表查询--分组

分组查询是指使用group by字句对查询信息进行分组。

l  格式:

SELECT 字段1,字段2… FROM 表名 GROUP BY分组字段 HAVING 分组条件;

分组操作中的having子语句,是用于在分组后对数据进行过滤的,作用类似于where条件。

l  having与where的区别:

n  having是在分组后对数据进行过滤.

where是在分组前对数据进行过滤

n  having后面可以使用分组函数(统计函数)

where后面不可以使用分组函数。

1.3.1 案例练习三

#1 统计各个分类商品的个数

SELECT category_id ,COUNT(*) FROM product GROUP BY category_id ;

#2 统计各个分类商品的个数,且只显示个数大于1的信息

SELECT category_id ,COUNT(*) FROM product GROUP BY category_id HAVING COUNT(*) > 1;

1.4  数据库的备份与还原

1.4.1 SQL备份

选中数据库,右键 ”备份/导出” , 指定导出路径,保存成.sql文件即可。

1.4.2 SQL恢复

数据库列表区域右键“从SQL转储文件导入数据库”, 指定要执行的SQL文件,执行即可。

第2章   SQL约束

2.1  SQL约束--主键约束

PRIMARY KEY 约束唯一标识数据库表中的每条记录。

主键必须包含唯一的值。

主键列不能包含 NULL 值。

每个表都应该有一个主键,并且每个表只能有一个主键。

2.1.1 添加主键约束

l  方式一:创建表时,在字段描述处,声明指定字段为主键:

CREATE TABLE Persons

(

Id_P int PRIMARY KEY,

LastName varchar(255),

FirstName varchar(255),

Address varchar(255),

City varchar(255)

)

l  方式二:创建表时,在constraint约束区域,声明指定字段为主键:

n  格式:[constraint 名称] primary key (字段列表)

n  关键字constraint可以省略,如果需要为主键命名,constraint不能省略,主键名称一般没用。

n  字段列表需要使用小括号括住,如果有多字段需要使用逗号分隔。声明两个以上字段为主键,我们称为联合主键。

CREATE TABLE Persons

(

FirstName varchar(255),

LastName varchar(255),

Address varchar(255),

City varchar(255),

CONSTRAINT pk_PersonID PRIMARY KEY (FirstName,LastName)

)

CREATE TABLE Persons

(

FirstName varchar(255),

LastName varchar(255),

Address varchar(255),

City varchar(255),

PRIMARY KEY (FirstName,LastName)

)

l  方式三:创建表之后,通过修改表结构,声明指定字段为主键:

ALTER TABLE Persons ADD [CONSTRAINT 名称] PRIMARY KEY (字段列表)

CREATE TABLE Persons

(

FirstName varchar(255),

LastName varchar(255),

Address varchar(255),

City varchar(255)

)

ALTER TABLE Persons ADD PRIMARY KEY (FirstName,LastName)

2.1.2 删除主键约束

如需撤销 PRIMARY KEY 约束,请使用下面的 SQL:

ALTER TABLE Persons DROP PRIMARY KEY

2.2  SQL约束--自动增长列

2.2.1 自动增长

我们通常希望在每次插入新记录时,数据库自动生成字段的值。

我们可以在表中使用 auto-increment(自动增长列)关键字,自动增长列类型必须是整形,自动增长列必须为键(一般是主键)。

l  下列 SQL 语句把 "Persons" 表中的 "P_Id" 列定义为 auto-increment 主键

CREATE TABLE Persons

(

P_Id int PRIMARY KEY AUTO_INCREMENT,

LastName varchar(255),

FirstName varchar(255),

Address varchar(255),

City varchar(255)

)

l  向persons添加数据时,可以不为P_Id字段设置值,也可以设置成null,数据库将自动维护主键值:

INSERT INTO Persons (FirstName,LastName) VALUES ('Bill','Gates')

INSERT INTO Persons (P_Id,FirstName,LastName) VALUES (NULL,'Bill','Gates')

l  面试:delete和truncate的区别

n  Delete删除表中的数据,但不重置auto-increment记录数。

n  Truncate删除表中的数据,auto-increment记录数将重置。Truncate其实先删除表然后再创建表。

l  扩展:默认地,AUTO_INCREMENT 的开始值是 1,如果希望修改起始值,请使用下列 SQL 语法:

ALTER TABLE Persons AUTO_INCREMENT=100

2.2.2 案例练习四

##自动增长列

CREATE TABLE ai01(

id INT PRIMARY KEY AUTO_INCREMENT,

NAME VARCHAR(50)

);

# 向表中插入数据

INSERT INTO ai01(NAME) VALUES('a');

INSERT INTO ai01(id,NAME) VALUES(NULL,'a');

## 自动增长列非法使用

CREATE TABLE ai02(

id VARCHAR(32) PRIMARY KEY AUTO_INCREMENT, #字段描述错误,类型不对

NAME VARCHAR(50)

);

CREATE TABLE ai03(

id INT  AUTO_INCREMENT,      #自动增长列必须是键(一般是主键)

NAME VARCHAR(50)

);

#扩展:设置自动增长列初始值,id默认值为1

CREATE TABLE ai04(

id INT PRIMARY KEY AUTO_INCREMENT,

NAME VARCHAR(50)

);

ALTER TABLE ai04 AUTO_INCREMENT = 100;

INSERT INTO ai04(NAME) VALUES('a');

#面试题 :delete 和 truncate 区别

## delete 删除表数据,但不重置自动增长列记录数。

##truncate 删除表数据,重置自动增长列的记录数。(先删除表,再创建表)

DELETE FROM ai01;

TRUNCATE TABLE ai01;

2.3  SQL约束--非空约束

NOT NULL 约束强制列不接受 NULL 值。

NOT NULL 约束强制字段始终包含值。这意味着,如果不向字段添加值,就无法插入新记录或者更新记录。

l  下面的 SQL 语句强制 "Id_P" 列和 "LastName" 列不接受 NULL 值:

CREATE TABLE Persons

(

Id_P int NOT NULL,

LastName varchar(255) NOT NULL,

FirstName varchar(255),

Address varchar(255),

City varchar(255)

)

 

2.4  SQL约束--唯一约束

UNIQUE 约束唯一标识数据库表中的每条记录。

UNIQUE 和 PRIMARY KEY 约束均为列或列集合提供了唯一性的保证。

PRIMARY KEY 拥有自动定义的 UNIQUE 约束。

请注意,每个表可以有多个 UNIQUE 约束,但是每个表只能有一个 PRIMARY KEY 约束。

2.4.1 添加唯一约束

与主键添加方式相同,共有3种,

l  方式1:创建表时,在字段描述处,声明唯一:

CREATE TABLE Persons

(

Id_P int UNIQUE,

LastName varchar(255) NOT NULL,

FirstName varchar(255),

Address varchar(255),

City varchar(255)

)

l  方式2:创建表时,在约束区域,声明唯一:

CREATE TABLE Persons

(

Id_P int,

LastName varchar(255) NOT NULL,

FirstName varchar(255),

Address varchar(255),

City varchar(255),

CONSTRAINT 名称UNIQUE (Id_P)

)

l  方式3:创建表后,修改表结构,声明字段唯一:

ALTER TABLE Persons ADD [CONSTRAINT 名称] UNIQUE (Id_P)

2.4.2 删除唯一约束

l  如需撤销 UNIQUE 约束,请使用下面的 SQL:

ALTER TABLE Persons DROP INDEX 名称

如果添加唯一约束时,没有设置约束名称,默认是当前字段的字段名。

2.4.3 案例练习五

##唯一约束

CREATE TABLE un01(

id VARCHAR(32),

NAME VARCHAR(50)

);

ALTER TABLE un01 ADD CONSTRAINT u0001 UNIQUE (id);

#删除

ALTER TABLE un01 DROP INDEX u0001;

##如果没有设置约束名称,唯一约束名称默认是字段名称

CREATE TABLE un02(

id VARCHAR(32),

NAME VARCHAR(50)

);

ALTER TABLE un02 ADD UNIQUE (id);

#删除

ALTER TABLE un02 DROP INDEX id;

第3章   多表操作

3.1  表与表之间的关系

l  一对多关系:

n  常见实例:客户和订单,分类和商品,部门和员工.

n  一对多建表原则:在从表(多方)创建一个字段,字段作为外键指向主表(一方)的主键.

l  多对多关系:

n  常见实例:学生和课程、用户和角色

n  多对多关系建表原则:需要创建第三张表,中间表中至少两个字段,这两个字段分别作为外键指向各自一方的主键.

l  一对一关系:(了解)

n  在实际的开发中应用不多.因为一对一可以创建成一张表.

n  两种建表原则:

u  外键唯一:主表的主键和从表的外键(唯一),形成主外键关系,外键唯一unique。

u  外键是主键:主表的主键和从表的主键,形成主外键关系。

3.2  外键约束

现在我们有两张表“分类表”和“商品表”,为了表明商品属于哪个分类,通常情况下,我们将在商品表上添加一列,用于存放分类cid的信息,此列称为:外键

此时“分类表category”称为:主表,“cid”我们称为主键。“商品表products”称为:从表,category_id称为外键。我们通过主表的主键和从表的外键来描述主外键关系,呈现就是一对多关系。

外键特点:

u  从表外键的值是对主表主键的引用。

u  从表外键类型,必须与主表主键类型一致。

l  声明外键约束

语法:alter table 从表 add [constraint] [外键名称] foreign key (从表外键字段名) references 主表 (主表的主键);

[外键名称] 用于删除外键约束的,一般建议“_fk”结尾

alter table 从表 drop foreign key 外键名称

l  使用外键目的:

n  保证数据完整性

3.3  一对多关系

3.3.1 一对多的表关系的分析与实现

3.3.1.1       分析

l  category分类表,为一方,也就是主表,必须提供主键cid

l  products商品表,为多方,也就是从表,必须提供外键category_id

3.3.1.2       实现:分类和商品

3.3.2 案例练习六

#创建数据库

CREATE DATABASE webdb_2;

#使用数据库

USE webdb_2;

####一对多关系

#1 创建主表:分类表

CREATE TABLE category(

cid VARCHAR(32) PRIMARY KEY,

cname VARCHAR(50)

);

#2 创建从表:商品表

CREATE TABLE products(

pid VARCHAR(32) PRIMARY KEY,

NAME VARCHAR(50),

price INT,

category_id VARCHAR(32)

);

#3 将使用 主外键关系进行描述

ALTER TABLE products ADD CONSTRAINT products_fk FOREIGN KEY (category_id) REFERENCES category (cid);

3.3.3 一对多关系操作

3.3.4 案例练习七

#数据操作

#1 向分类表中插入数据

INSERT INTO category(cid,cname) VALUES('c001','服装');

#2 向商品表中插入数据,不含外键信息

INSERT INTO products(pid,NAME,price) VALUES('p001','KAMA服饰',100);

## 结论:外键数据默认可以为null

#3 向商品表中插入数据,含外键信息 (数据存在)

INSERT INTO products(pid,NAME,price,category_id) VALUES('p002','KAMA服饰2',100,'c001');

#4 向商品表中插入数据,含外键信息 (数据不存在)

INSERT INTO products(pid,NAME,price,category_id) VALUES('p003','KAMA服饰2',100,'c999');

## 结论:从表不能添加(或更新),主表不存在的数据。

#5 删除分类表的数据

#delete from products where category_id = 'c001';   #实际开发中解决方案

DELETE FROM category WHERE cid = 'c001';

## 结论:主表不能删除(或更新),从表中已经使用的数据。

#扩展:在一对多关系中,存在一种父子关系,主表又称为父表,从表又称为子表。

3.4  多对多关系

3.4.1 多对多表关系的分析和实现

l  商品和订单多对多关系,将拆分成两个一对多。

l  products商品表,为其中一个一对多的主表,需要提供主键pid

l  orders 订单表,为另一个一对多的主表,需要提供主键oid

l  orderitem中间表,为另外添加的第三张表,需要提供两个外键oid和pid

3.4.2 案例练习八

#1 商品表[存在]

#2 订单表

CREATE TABLE orders(

oid VARCHAR(32) PRIMARY KEY,

totalprice INT   #总价

);

#3 中间表

CREATE TABLE orderitem(

product_id VARCHAR(32), #对应商品表 products.pid

order_id VARCHAR(32)    #对应订单表 orders.oid

);

#4 描述2次,主外键关系

#4.1 中间表 与 商品表 主外键关系

ALTER TABLE orderitem ADD CONSTRAINT orderitem_product_fk FOREIGN KEY (product_id) REFERENCES products (pid);

#4.2 中间表 与 订单表 主外键关系

ALTER TABLE orderitem ADD CONSTRAINT orderitem_order_fk FOREIGN KEY (order_id) REFERENCES orders (oid);

#5 扩展:中间表2个外键字段,一般形成联合主键(2个组合在一起唯一)[可选]

ALTER TABLE orderitem ADD CONSTRAINT PRIMARY KEY (product_id , order_id);

3.4.3 多对多表关系的操作

3.4.4 案例练习九

###操作

#1 向商品表插入数据

INSERT INTO products(pid,NAME,price) VALUES('p003','商品001',998);

#2 向订单表插入数据

INSERT INTO orders(oid,totalprice) VALUES('x001',100);

#3 向中间表插入数据(存在)

INSERT INTO orderitem(product_id,order_id) VALUES('p003','x001');

INSERT INTO orderitem(product_id,order_id) VALUES('p002','x001');

## 结论:多对多关系,如果两个主表建立联系,需要向中间表插入数据。

#4 删除中间表的数据

DELETE FROM orderitem WHERE product_id = 'p003' AND order_id = 'x001';

#5 向中间表插入数据(不存在)  -- 运行异常

INSERT INTO orderitem(product_id,order_id) VALUES('p003','x002');

-- 注意:维护中间表时,数据必须存在

#6 删除订单表(主表)数据(被使用中) -- 运行异常

DELETE FROM orders WHERE oid = 'x001';

###一对多和多对多操作对比

#一对多维护关系时,操作从表的外键(一个字段)

#多对多维护关系时,操作整个中间表(一张表)

java基础-day29的更多相关文章

  1. Java基础知识(壹)

    写在前面的话 这篇博客,是很早之前自己的学习Java基础知识的,所记录的内容,仅仅是当时学习的一个总结随笔.现在分享出来,希望能帮助大家,如有不足的,希望大家支出. 后续会继续分享基础知识手记.希望能 ...

  2. [Java面经]干货整理, Java面试题(覆盖Java基础,Java高级,JavaEE,数据库,设计模式等)

    如若转载请注明出处: http://www.cnblogs.com/wang-meng/p/5898837.html   谢谢.上一篇发了一个找工作的面经, 找工作不宜, 希望这一篇的内容能够帮助到大 ...

  3. 【JAVA面试题系列一】面试题总汇--JAVA基础部分

    JAVA基础 基础部分的顺序: 基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法 线程的语法,集合的语法,io 的语法,虚拟机方面的语法 每天几道,持续更新!! 1.一个". ...

  4. 最适合作为Java基础面试题之Singleton模式

    看似只是最简单的一种设计模式,可细细挖掘,static.synchronized.volatile关键字.内部类.对象克隆.序列化.枚举类型.反射和类加载机制等基础却又不易理解透彻的Java知识纷纷呼 ...

  5. java基础练习 字符串,控制流,日历,日期等

    1,对基本控制流程的一些练习 package org.base.practice3; import org.junit.Test; /** * Created with IntelliJ IDEA. ...

  6. Java基础知识【下】( 转载)

    http://blog.csdn.net/silentbalanceyh/article/details/4608360 (最终还是决定重新写一份Java基础相关的内容,原来因为在写这一个章节的时候没 ...

  7. Java基础知识【上】(转载)

    http://blog.csdn.net/silentbalanceyh/article/details/4608272 (最终还是决定重新写一份Java基础相关的内容,原来因为在写这一个章节的时候没 ...

  8. java基础学习03(java基础程序设计)

    java基础程序设计 一.完成的目标 1. 掌握java中的数据类型划分 2. 8种基本数据类型的使用及数据类型转换 3. 位运算.运算符.表达式 4. 判断.循环语句的使用 5. break和con ...

  9. Java基础加强之多线程篇(线程创建与终止、互斥、通信、本地变量)

    线程创建与终止 线程创建 Thread类与Runnable接口的关系 public interface Runnable { public abstract void run(); } public ...

随机推荐

  1. c# sql 复制表后提示列无效解决办法

    --CREATE TABLE [dbo].[JinanCount] SELECT * FROM [dbo].[ChengXiangCount]   这条指令错误select * into [dbo]. ...

  2. Informatica_(6)性能调优

    六.实战汇总31.powercenter 字符集 了解源或者目标数据库的字符集,并在Powercenter服务器上设置相关的环境变量或者完成相关的设置,不同的数据库有不同的设置方法: 多数字符集的问题 ...

  3. Oracle_高级功能(6) 分区

    oracle分区表1.分区表: 当表中的数据量不断增大,查询数据的速度就会变慢,应用程序的性能就会下降,这时就应该考虑对表进行分区. 表进行分区后,逻辑上表仍然是一张完整的表,只是将表中的数据在物理上 ...

  4. URLEncoder.encode转译后“空格”变“加号”的问题的解决方案

    我用dst_fname=URLEncoder.encode(dst_fname);对字符串dst_fname进行编码,但是发现空格全部都变成了加号,我们提需求的傻B非得要空格的,但是不编码有很多非常特 ...

  5. 分析入口文件main.php

    在分析之前,需要了解php cli模式下的编程 1.了解getopt函数,php手册地址:http://php.net/manual/zh/function.getopt.php static pri ...

  6. SVN查看最新几次提交日志的命令

    Windows下,使用svn客户端查看日志很方便,linux下查看的记录条数的小技巧: 1>查看某个目录下的所有日志记录 svn log [PATH] 上面的方式,对于命令行下查看时是很不方便的 ...

  7. BZOJ1855或洛谷2569 [SCOI2010]股票交易

    一道单调队列优化\(DP\) BZOJ原题链接 洛谷原题链接 朴素的\(DP\)方程并不难想. 定义\(f[i][j]\)表示到第\(i\)天,手上持有\(j\)股时的最大收益. 转移方程可以分成四个 ...

  8. Python之路(第二篇):Python基本数据类型字符串(一)

    一.基础 1.编码 UTF-8:中文占3个字节 GBK:中文占2个字节 Unicode.UTF-8.GBK三者关系 ascii码是只能表示英文字符,用8个字节表示英文,unicode是统一码,世界通用 ...

  9. java Mather 的 group 含义

    参考博文:  http://blog.csdn.net/java2king/article/details/4395067  明白了group 的 含义 public class Test { pub ...

  10. Java设计模式(8)——策略模式

    一.策略模式定义 Strategy模式也叫策略模式是行为模式之一,它对一系列的算法加以封装,为所有算法定义一个抽象的算法接口,并通过继承该抽象算法接口对所有的算法加以封装和实现,具体的算法选择交由客户 ...