Android基础知识-数据库基础

转载

https://code.tutsplus.com/articles/sql-for-beginners–net-8200
https://code.tutsplus.com/articles/sql-for-beginners-part-2–net-8274
https://code.tutsplus.com/articles/sql-for-beginners-part-3-database-relationships–net-8561

常用Sql

功能SQL语句说明
创建数据库CREATE DATABASE my_first_db;

CREATE DATABASE my_db
DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
设置字符集 utf8
后缀"_cs"、"_ci"表示 区分大小写、不区分大小写
( Case Sensitive & Case Insensitve)
utf8_general_ci 表示不区分大小写
列出所有数据库SHOW DATABASES;
删除数据库DROP DATABASE my_db;
选择一个数据库USE my_db;
创建/删除表CREATE TABLE users (username VARCHAR(20), create_date DATE);
DROP TABLE users; //删除表
列出数据库所有表SHOW TABLES;
展示表结构EXPLAIN users;
修改表-增加字段ALTER TABLE users ADD email VARCHAR(100) AFTER username;
修改表-修改字段ALTER TABLE users CHANGE username user_name VARCHAR(30)
插入数据
VALUES 方式
INSERT INTO users
VALUES(NULL, ‘johndoe’, ‘john@doe.com’, ‘2009-12-14’);
插入数据
SET 方式
INSERT INTO users SET user_name = ‘nettuts’, email = ‘nettuts@gmail.com’;
NOW() 关键字INSERT INTO users SET create_date = NOW(), user_name = ‘batman’;
LAST_INSERT_ID()
查询最后一次插入数据的ID
SELECT LAST_INSERT_ID();
查询当前时间SELECT NOW();
WHERE 条件语句SELECT * FROM users WHERE create_date != ‘2009-12-14’;
SELECT * FROM users WHERE user_id <= 2;
AND、OR 关键字SELECT * FROM users WHERE user_id = 1 OR user_name = ‘nettuts’;
IN() 语句SELECT * FROM users WHERE create_date IN (‘2009-12-15’, ‘2019-12-15’);
LIKE 关键字 %作为通配符SELECT * FROM users WHERE email LIKE ‘%TUTS%’;
DESC降序排列
默认 ASC升序排列
SELECT * FROM users ORDER BY user_name DESC;
LIMIT … OFFSET …
LIMIT 1,表示获取 1 条结果
OFFSET 2,表示从头两条数据之后开始算起
SELECT * FROM users LIMIT 1 OFFSET 2;
更新某条数据UPDATE users SET create_date = ‘2009-12-01’
WHERE create_date = ‘2009-12-14’ LIMIT 1;
删除某条数据DELETE FROM users WHERE user_name = ‘batman’;
TRUNCATE:重置表
自增长的字段数据也会被重置
TRUNCATE TABLE users;
//DELETE:删除表数据
不会重置自增长的字段数据
DELETE FROM users;
反斜杠 \ 转义字符INSERT INTO users SET user_name = 'O\‘Reilly’;表中 user_name 的值 为 O’Reilly
把 ’ 当作字符串写入数据库。
关键字(select、delete、insert等)
不能作为表的字段,否则会报错
主键 PRIMARY KEYCREATE TABLE states (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(20));
CREATE TABLE states (id INT AUTO_INCREMENT, name VARCHAR(20), PRIMARY KEY (id));
唯一不可重复 UNIQUECREATE TABLE states (id INT AUTO_INCREMENT, name VARCHAR(20), UNIQUE (name));
设置 name 字段唯一
并且 索引名为 state_name
CREATE TABLE states (id INT AUTO_INCREMENT,name VARCHAR(20), PRIMARY KEY (id),UNIQUE state_name (name));
创建索引CREATE TABLE states (id INT AUTO_INCREMENT, join_year INT,PRIMARY KEY (id), INDEX (join_year));
创建索引
用 KEY 关键字 代替 INDEX 关键字
CREATE TABLE states (id INT AUTO_INCREMENT, join_year INT, PRIMARY KEY (id), KEY (join_year));
GROUP BY 分组
BY 后面跟字段名
表示根据某个字段分组
SELECT * FROM states GROUP BY join_year;
COUNT(*) 计数函数
与 GROUP BY配合使用
SELECT COUNT(*), join_year FROM states GROUP BY join_year;
MIN()最小值函数
MAX()最大值函数
AVG()平均数函数
SELECT MIN(population), MAX(population), AVG(population) FROM states;
GROUP_CONCAT()
将group by产生的同一个分组中的值连接起来
返回一个字符串结果
SELECT GROUP_CONCAT(name SEPARATOR ', '), join_year FROM states GROUP BY join_year;根据 join_year 分组
把每个分组所有元素的name用逗号 ‘,’ 分隔拼接成字符串返回,还有返回join_year
SUM() 求和SELECT SUM(population) AS usa_population FROM states;查询 states表中所有元素的 population 之和
以 usa_population为别名返回
IF() 语句SELECT IF(true, ‘foo’, ‘bar’);//返回 foo
SELECT IF(false, ‘foo’, ‘bar’);//返回 bar
该语句有三个参数
参数一:条件
参数二:条件为 true,的返回值
参数三:条件为 false,的返回值
CASESELECT
COUNT(*),
CASE
WHEN
population > 5000000 THEN 'big’
WHEN population > 1000000 THEN ‘medium’
ELSE ‘small’ END
AS state_size
FROM states GROUP BY state_size;
计数,返回 state_size字段和数量,
population > 5000000 时 state_size 的值为 big
population > 1000000 时 state_size 的值为 medium
population <= 1000000时 state_size 的值为 small
HAVING
GROUP BY 配合使用的条件句
SELECT COUNT(*), join_year FROM states GROUP BY join_year HAVING COUNT(*) > 1;
多重查询SELECT * FROM states
WHERE join_year = (SELECT MAX(join_year) FROM states);
从一个查询语句的结果中查询
IN()
在IN(…)条件之内的数据
SELECT * FROM states WHERE join_year IN (
  SELECT join_year FROM states
  GROUP BY join_year
  HAVING COUNT(*) > 1
) ORDER BY join_year;
UNION 合并数据(SELECT * FROM states WHERE name LIKE ‘n%’)
  UNION
(SELECT * FROM states WHERE population > 10000000);
REPLACE INFOREPLACE INFO products SET name = ‘breadmaker’, stock = 5;类似INSERT 语句的作用
插入 UNIQUE 字段重复的数据时,不会报错
会先删除旧数据,然后插入本条数据
id会自增
INSERT IGNOREINSERT IGNORE INTO products SET name = ‘breadmaker’;插入UNIQUE 字段重复的数据时,不再报错,并不能插入成功
INSERT …
ON DUPLICATE KEY UPDATE
假设 name 是 UNIQUE 字段

INSERT INTO products SET name = ‘breadmaker’, stock = 1 ON DUPLICATE KEY UPDATE name= ‘breadmaker2’;

插入name字段重复的数据时
把插入数据的name字段改为 breadmaker2
INSERT INTO插入 UNIQUE字段重复的数据时,会报错。
可以使用 INSERT …
ON DUPLICATE KEY UPDATE
避免错误

表关系

两张表:

CREATE TABLE customers(
customers_id INT AUTO_INCREMENT PRIMARY KEY,
customers_name VARCHAR(100)
);

//明确声明 customer_id 字段为外键,并关联 customers表的 customer_id 字段
CREATE TABLE orders(
orders_id INT AUTO_INCREMENT PRIMARY KEY,
customer_id INT
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);

关系sql语句说明
FOREIGN KEY 外键CREATE TABLE orders(

FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);
使用 JOIN 查询检索数据时
即使数据库引擎不知道该关系,仍然可以将此列视为外键
Cross Join
全外连接
SELECT * FROM customers CROSS JOIN orders;结果是“笛卡尔积
第一张表每一行 都与 第二张表中的每一行匹配。
假设每个表有 4行,最终会得到 16行 的结果
Natural JoinSELECT * FROM customers NATURAL JOIN orders;使用这种JOIN查询,表要具有名字相同的列名
Demo中,两个表都具有 _id 列,
仅当此列 _id 的值在两条记录上匹配时,才会加入记录
(根据相同列名来匹配)
Inner Join
等值连接 / 内连接
SELECT * FROM customers JOIN orders
WHERE customers.customers _id = orders.customers _id;
只返回 两个表中 连接字段相等 的行
ON 语句SELECT * FROM customers JOIN orders
ON (customers.customers_id = orders.customers_id) WHERE orders.amount > 15;
USING 语句SELECT * FROM customers JOIN orders
USING (customers_id) WHERE orders.amount > 15;
类似 ON 语句
两个表,有相同名字的字段 时,可用 USING 来指定
Left (Outer) JoinSELECT * FROM customers LEFT OUTER JOIN orders
USING (customers_id);
左表所有记录 + 右表连接字段相等的记录
Right (Outer) JoinSELECT * FROM customers RIGHT OUTER JOIN orders
USING (customers_id);
右表所有记录 + 左表中连接字段相等记录

数据类型

数据类型字节数最小值最大值
TINYINT1 字节-128127
SMALLINT2 字节-3276832767
MEDIUMINT3 字节
INT4 字节
BIGINT8 字节
FLOAT4 字节
DOUBLE8 字节
DECIMAL(M,N)最多包含M个整数、N个小数位
CHAR(N)
VARCHAR(N)
TEXT
DATE‘1001-01-01’‘9999-12-31’
DATETIME‘1001-01-01 00:00:00’‘9999-12-31 23:59:59’
TIMESTAMP‘1970-01-01 00:00:01’ UTC‘2038-01-19 03:14:07’ UTC
TIME只能保存 ‘时分秒’
YEAR只能保存 ‘年’,比如 ‘2019’

1、常用 SQL

1)创建/删除/使用数据库

CREATE DATABASE my_first_db;
/* EFAULT CHARACTER SET utf8:设置字符集 utf8
 * COLLATE utf8_general_ci(后缀"_cs"或者"_ci"意思是区分大小写和不区分大小写(Case Sensitive & Case Insensitve))
 * 							这里utf8_general_ci表示不区分大小写
 */
CREATE DATABASE my_first_db DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
//列出所有数据库
SHOW DATABASES;
//删除数据库
DROP DATABASE my_first_db;
//选择一个数据库
USE my_first_db;

2)创建/删除表

//创建users表,字段 username 字符类型,字段 create_date 日期类型
CREATE TABLE users (username VARCHAR(20), create_date DATE);
//user_id INT AUTO_INCREMENT PRIMARY KEY:主键 user_id INT类型 自增长
CREATE TABLE users (user_id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(20), create_date DATE);
//列出所选数据库的所有表
SHOW TABLES;
//展示表结构
EXPLAIN users;
//删除表
DROP TABLE users;
//修改表-增加字段:在 username字段后面增加 email 字段
ALTER TABLE users ADD email VARCHAR(100) AFTER username;
//修改表-删除字段
ALTER TABLE users DROP email;
//修改表-修改字段:把username 字段 改为 user_name 字符长度改为30
ALTER TABLE users CHANGE username user_name VARCHAR(30)

3)插入表数据

//插入数据 VALUES 方式
INSERT INTO users VALUES(NULL, 'johndoe', 'john@doe.com', '2009-12-14');
//插入数据 SET 方式
INSERT INTO users SET user_name = 'nettuts', email = 'nettuts@gmail.com',create_date = '2019-12-14';
//插入数据
INSERT INTO users (email, user_name, create_date) VALUES ('foo@bar.com', 'foobar','2019-12-16');
//NOW() 关键字
INSERT INTO users SET create_date = NOW(), user_name = 'batman', email = 'bat@man.com';

4)查询表数据

//LAST_INSERT_ID():查询最后一次插入数据的ID
SELECT LAST_INSERT_ID();
//查询当前时间
SELECT NOW();
//查询表中所有字段
SELECT * FROM users;
//查询表中指定字段
SELECT user_name, email FROM users;
//WHERE 条件语句
SELECT email FROM users WHERE user_name='nettuts';
SELECT * FROM users WHERE user_id <= 2;
SELECT * FROM users WHERE create_date != '2009-12-14';
//AND、OR 关键字
SELECT * FROM users WHERE user_id = 1 OR user_name = 'nettuts';
//IN() 语句
SELECT * FROM users WHERE create_date IN ('2009-12-15', '2019-12-15');
//LIKE 关键字 %作为通配符
SELECT * FROM users WHERE email LIKE '%TUTS%';
//ORDER BY 语句
SELECT * FROM users ORDER BY create_date;
//DESC降序排列;默认是 ASC升序排列
SELECT * FROM users ORDER BY user_name DESC;
/* LIMIT ... OFFSET ...
 * LIMIT 1,表示获取 1 条结果
 * OFFSET 2,表示从头两条数据之后开始算起
 */
SELECT * FROM users LIMIT 1 OFFSET 2;

5)更新表数据

//修改某条数据
UPDATE users SET email = 'changed@gmail.com', user_name = 'barfoo' WHERE user_name = 'foobar';

UPDATE users SET create_date = '2009-12-01' WHERE create_date = '2009-12-14' LIMIT 1;

6)删除表数据

//DELETE
DELETE FROM users WHERE user_name = 'batman';
//TRUNCATE:重置表,自增长的字段数据也会被重置
TRUNCATE TABLE users;
//DELETE:删除表数据,不会重置自增长的字段数据
DELETE FROM users;

7)特殊字符

i. 反斜杠 \ 转义字符
	INSERT INTO users SET user_name = 'O\'Reilly';
	插入后,表中 user_name 的值 为 O'Reilly,把 ' 当作字符串写入数据库。

ii. 关键字(select、delete、insert等)不能作为表的字段,否则会报错

8)主键 PRIMARY KEY

//创建主键的方式
CREATE TABLE states (
	id INT AUTO_INCREMENT PRIMARY KEY, 
	name VARCHAR(20)
);
CREATE TABLE states (
	id INT AUTO_INCREMENT, 
	name VARCHAR(20), 
	PRIMARY KEY (id)
);

9)唯一不可重复 UNIQUE

//设置 name 字段唯一,索引名默认为字段名 name
CREATE TABLE states (
	id INT AUTO_INCREMENT,
	name VARCHAR(20),
	PRIMARY KEY (id),
	UNIQUE (name)
);
//设置 name 字段唯一,并且索引名为 state_name
CREATE TABLE states (
	id INT AUTO_INCREMENT,
	name VARCHAR(20),
	PRIMARY KEY (id),
	UNIQUE state_name (name)
);

10)INDEX 索引

//创建索引
CREATE TABLE states (
	id INT AUTO_INCREMENT,
	name VARCHAR(20),
	join_year INT,
	PRIMARY KEY (id),
	UNIQUE (name),
	INDEX (join_year)
);
//可以用 KEY 关键字 代替 INDEX 关键字
CREATE TABLE states (
	id INT AUTO_INCREMENT,
	name VARCHAR(20),
	join_year INT,
	PRIMARY KEY (id),
	UNIQUE (name),
	KEY (join_year)
);

11)GROUP BY 分组:BY 后面跟字段名,表示根据某个字段分组

//根据 join_year 字段分组,join_year值相同的数据会分为一组
SELECT * FROM states GROUP BY join_year;

12)COUNT(*) 计数函数,常与 GROUP BY配合使用

//根据join_year进行分组,并计算每组数量,返回 每组数量 和 join_year
SELECT COUNT(*), join_year FROM states GROUP BY join_year;
//返回 states表数据条数
SELECT COUNT(*) FROM states;
//查询 join_year = 1787 的数据条数
SELECT COUNT(*) FROM states WHERE join_year = 1787;

13)MIN()最小值函数, MAX()最大值函数, AVG()平均数函数

//查询states表中 population的最小值、最大值、平均值
SELECT MIN(population), MAX(population), AVG(population) FROM states;

14)GROUP_CONCAT() 将group by产生的同一个分组中的值连接起来,返回一个字符串结果。

/* 查询states表,根据join_year进行分组,把每个分组所有元素的name用逗号','分隔拼接成字符串返回,
 * 还有返回join_year
 */
SELECT GROUP_CONCAT(name SEPARATOR ', '), join_year FROM states GROUP BY join_year;

15)SUM() 求和

//查询 states表中所有元素的 population 之和,以 usa_population为别名返回
SELECT SUM(population) AS usa_population FROM states;

16)IF() 语句

该语句有三个参数,参数一:条件   参数二:条件为true时的返回值  参数三:条件为false时的返回值

//返回 foo
SELECT IF(true, 'foo', 'bar');
//返回 bar
SELECT IF(false, 'foo', 'bar');

/* 每次查到 population > 5000000 的数据 big_states 的结果+1,
 *           population <=5000000的数据 big_states的结果+0
 *
 * 每次查到 population <= 5000000 的数据 small_states 的结果+1,
 *           population >5000000的数据 small_states 的结果+0
 *
 * 最后返回 big_states、small_states的值
 */
SELECT
	SUM(
		IF(population > 5000000, 1, 0)
	) AS big_states,
 
	SUM(
		IF(population <= 5000000, 1, 0)
	) AS small_states
FROM states;

17)CASE

/* 计数,返回 state_size字段和数量,
 *		population > 5000000 时 state_size 的值为 big
 *		population > 1000000 时 state_size 的值为 medium
 *		population <= 1000000时 state_size 的值为 small
 */
SELECT
COUNT(*),
CASE
	WHEN population > 5000000 THEN 'big'
	WHEN population > 1000000 THEN 'medium'
	ELSE 'small' END
	AS state_size
FROM states GROUP BY state_size;

18)HAVING

//与GROUP BY 配合使用的条件句
SELECT COUNT(*), join_year FROM states GROUP BY join_year HAVING COUNT(*) > 1;

19)多重查询

//从一个查询语句的结果中查询
SELECT * FROM states WHERE join_year = (
	SELECT MAX(join_year) FROM states
);

20)IN() 在IN(…)条件之内的数据

SELECT * FROM states WHERE join_year IN (
	SELECT join_year FROM states
	GROUP BY join_year
	HAVING COUNT(*) > 1
) ORDER BY join_year;

21)UNION 合并数据

(SELECT * FROM states WHERE name LIKE 'n%')
UNION
(SELECT * FROM states WHERE population > 10000000);

22)INSERT … ON DUPLICATE KEY UPDATE

前提条件设置:
	创建表,name字段唯一
	CREATE TABLE products (
		id INT AUTO_INCREMENT PRIMARY KEY,
		name VARCHAR(20),
		stock INT,
		UNIQUE (name)
	);
	//插入数据 name = 'breadmaker', stock = 10
	INSERT INTO products SET name = 'breadmaker', stock = 10;
此时如果再插入 name = 'breadmaker' 的数据会报错,Dup里擦忒entry 'breadmaker' for key 'name'

需要执行以下SQL语句:
INSERT INTO products SET name = 'breadmaker', stock = 1 ON DUPLICATE KEY UPDATE stock = stock + 1;

23)REPLACE INFO

该语句类似INSERT 语句的作用,但是对于UNIQUE字段的数据,INSERT 插入该字段重复的数据时会报错。

REPLACE INFO 插入UNIQUE字段重复的数据时,不会报错,
会先删除旧数据,然后插入本条数据,id会自增。

REPLACE INFO products SET name = 'breadmaker', stock = 5;

24)INSERT IGNORE

该语句可以避免插入UNIQUE字段重复的数据时报错,但是只是不再报错,并不能插入成功

INSERT IGNORE INTO products SET name = 'breadmaker', stock = 1;

2、字段的数据类型

1)整数 数据类型

类型        字节数          最小值   		最大值
TINYINT 	  1   			  -128			  127
SMALLINT	  2				  -32768         32767
MEDIUMINT	  3             
INT			  4				
BIGINT		  8

2)非整数 的数字数据类型

FLOAT  		4 字节
DOUBLE 		8 字节
DECIMAL(M,N)     最多包含M个整数和N个小数位

3)字符串数据类型

CHAR(N)
VARCHAR(N)
TEXT

4)日期类型

DATE		范围 '1001-01-01' 到 '9999-12-31'
DATETIME 	范围 '1001-01-01 00:00:00' 到 '9999-12-31 23:59:59'
TIMESTAMP	范围 '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC
TIME		只能保存'时分秒'
YEAR		只能保存 '年'  比如 '2019'

3、表关系

1)FOREIGN KEY 外键

CREATE TABLE customers (
	customer_id INT AUTO_INCREMENT PRIMARY KEY,
	customer_name VARCHAR(100)
);

//明确声明customer_id字段为外键,并关联 customers表的customer_id字段
CREATE TABLE orders (
	order_id INT AUTO_INCREMENT PRIMARY KEY,
	customer_id INT,
	amount DOUBLE,
	FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);

//不需要明确声明customer_id为外键,而是声明为索引
CREATE TABLE orders (
	order_id INT AUTO_INCREMENT PRIMARY KEY,
	customer_id INT,
	amount DOUBLE,
	INDEX (customer_id)
);
//使用JOIN查询检索数据时,即使数据库引擎不知道该关系,您仍然可以将此列视为外键。
SELECT * FROM orders JOIN customers USING(customer_id)

2)Cross Join
(全外连接):返回左右表中所有的记录和左右表中连接字段相等的记录。
/* 下面是有外键关系时的写法
* 结果是“笛卡尔积”,第一张表中的每一行都与第二张表中的每一行匹配。
* 由于每个表有4行,因此最终得到16行的结果
*/
SELECT * FROM customers JOIN orders;
等同于:
SELECT * FROM customers, orders;

3)Natural Join

使用这种JOIN查询,表需要具有匹配的列名。 在我们的例子中,两个表都具有 customer_id 列。 
因此,仅当此列 customer_id 的值在两条记录上匹配时,才会加入记录

SELECT * FROM customers NATURAL JOIN orders;

4)Inner Join
(等值连接或者叫内连接):只返回两个表中连接字段相等的行。
指定连接条件后,将执行内部连接。 在这种情况下,最好使两个表上的customer_id字段都匹配。
结果应类似于自然联接。

SELECT * FROM customers JOIN orders WHERE customers.customer_id = orders.customer_id;

5)ON 语句

SELECT * FROM customers JOIN orders ON (customers.customer_id = orders.customer_id) 
WHERE orders.amount > 15;

6)USING 语句
类似 ON 语句,当两个表有名字相同的字段时,可以通过USING 来指定

SELECT * FROM customers JOIN orders USING (customer_id) WHERE orders.amount > 15;

7)Left (Outer) Join
左联接是外联接的一种。
返回包括左表中的所有记录和右表中连接字段相等的记录。

SELECT * FROM customers LEFT OUTER JOIN orders USING (customer_id);

SELECT * FROM customers LEFT OUTER JOIN orders USING (customer_id) 
WHERE orders.order_id IS NULL;

SELECT * FROM customers LEFT OUTER JOIN orders USING (customer_id) 
WHERE orders.amount > 15;

SELECT * FROM customers LEFT OUTER JOIN orders USING (customer_id) 
WHERE orders.amount > 15 OR orders.order_id IS NULL;

SELECT * FROM customers LEFT OUTER JOIN orders 
ON (customers.customer_id = orders.customer_id AND orders.amount > 15);

8)Right (Outer) Join
右联接是外联接的一种。
返回包括右表中的所有记录和左表中连接字段相等的记录。

SELECT * FROM customers RIGHT OUTER JOIN orders USING (customer_id);

SELECT * FROM orders RIGHT OUTER JOIN customers USING (customer_id);

推荐阅读:
数据库基础1
数据库基础2
数据库基础3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值