mac如何在命令行中进入默认的MySQL数据库
-
mysql.server start
开启数据库服务器,因为MySQL是客户-服务的数据库操作系统。 -
mysql -u root
使用无密码的root用户名登陆。
mac使用SequelPro连接本地MySQL
- host:127.0.0.1
- name:root
- port:3306(默认)
- 其他不用填
一:使用数据库
一般来说,我们会将关键字大写,表名,列名小写。关键字也可以小写。mysql语句不区分大小写关键字。
(一) 查看当前MySQL当中的所有数据库
SHOW DATABASES;
(二)使用某一个数据库前,必须指明要使用的数据库名字
USE databaseName;
查看当前数据库中的所有表
SHOW TABLES;
(三)查看当前表中的所有列名
SHOW COLUMNS FROM tableName;
或者
DESCRIBE tableName;
二:检索数据
(一)SELECT
- 单个列查询
SELECT age FROM user;
- 多列查询
SELECT name,age FROM user;
- 查询所有列
SELECT * FROM user;
- 过滤相同的行。比如当年龄为20的有五个人时,只会返回一个20
SELECT DISTINCT age FROM user;
- 限制结果。从第四行,开始检索五行。因此如果仅仅是
LIMIT 4
就表示从第零行,检索4行。
SELECT age FROM user LIMIT 3,5;
(二)排序检索数据
- 单个列排序。也可以使用非检索的列来排序。
SELECT age FROM user ORDER BY age;
- 多个列排序。先按年龄排序,如果年龄相等,再按照姓名排序。默认是ASC升序排列。
SELECT age,name FROM user ORDER BY age,name;
- 多列排序。先按年龄降序排列,如果年龄相等,就会再按姓名排序。
SELECT age,name FROM user ORDER BY age DESC,name;
- 寻找年龄最大的人
SELECT age FROM user ORDER BY age DESC LIMIT 1;
注意上面的LIMIT需要再ORDER BY之后,不然就变成了查询数据库的限制,而不是查询数据库结果之后的限制了。
(三)过滤数据
1: WHERE关键字。会返回所有满足条件的结果。ORDER BY应该用在WHERE之后。
SELECT age,name FROM user WHERE age=20;
- WHERE支持的操作符
操作符 | 说明 |
---|---|
= | 等于 |
<> | 不等于 |
!= | 不等于 |
< | 小于 |
> | 大于 |
<= | 小于等于 |
>= | 大于等于 |
BETWEEN | 在指定的两个值之间 |
- 使用限定引号
SELECT age,name FROM user WHERE name <> 'android';
- 范围值。在开始值和结束值之间还需要使用AND。
SELECT age,name FROM user WHERE age BETWEEN 18 AND 30;
- 检查NULL
SELECT age,name FROM user WHERE name IS NULL;
上面的语句会返回名字为NULL的行。
- AND操作符,可以多个AND联合使用
SELECT age,name,address FROM user WHERE address = 'beijing' AND age<=30;
上面这条语句表时返回地址是beijing,并且年龄小于等于30行。
- OR操作符。AND优先级高于OR的优先级
SELECT age,name,address FROM user WHERE age=20 OR age=25;
返回年龄是20或者25的行。
- 使用圆括号
SELECT age,name,address FROM user WHERE (age=20 OR age = 25) AND address="beijing";
2:IN操作符
SELECT age,name,address FROM user WHERE age IN (20,25,18) ORDER BY name;
返回年龄在20,25,18这三个岁数的行,并且按照名字排序。
3:NOT操作符
否定NOT后所跟的条件
SELECT age,name,address FROM user WHERE age NOT IN(50,40);
返回年龄不是50,40的所有行。
4:通配符过滤
LIKE指示后跟的搜索模式使用通配符而不是直接相等匹配。
SELECT age,name FROM user WHERE name LIKE 'xia%';
上面标示返回所有name以xia开头的行。
%标示任何字符出现任意次数。xia%标示,不管xia后面跟的是啥,跟了多少个。
而%xia%,则表示只要包含着xia就会返回。%不会匹配NULL。如果这里使用了WHERE age LIKE '20'
那么并不会返回年龄是20的行。但是把LIKE换成REGEXP就可以。
SELECT age,name FROM user WHERE name LIKE 'x_a';
_下划线只匹配一个字符。不能匹配0个或多个。
5:正则表达式
使用关键字REGEXP
SELECT age FROM user WHERE name REGEXP 'xia|nie'
返回匹配xia或者nie的行。
SELECT age FROM user WHERE name REGEXP '[xyz]ia'
返回匹配xia或者yia或者zia的行。其中’[xyz]xia‘也可以写'[x-z]ia';
SELECT age FROM user WHERE name REGEXP '[^xyz]ia'
返回匹配除xia或者yia或者zia的所有的行。
用“\\”加在所有特殊符号之前进行特殊符号匹配。之所以需要两个是因为MySQL解释一个,正则表达式解释一个。
^用在集合中否定,否则表示开始位置。
不使用数据库测试正则表达式
SELECT 'hello' REGEXP '[0-9]'
(四)在SELECT中创建计算字段
- 拼接两个列。MySql使用Concat(),其他sql或许可以使用+或者用||来拼接。
SELECT Concat(name,'(',age,')') FROM user ;
上面就回以name(age)的方式输出。实际上Concat是将name,(,age,)一共四个部分组合到一起的。
SELECT Concat(RTrim(name),'(',age,')') FROM user ;
在上面的基础上,通过函数Trim(name)去掉了name中的左右两边空格。
SELECT Concat(RTrim(name),'(',age,')') AS title FROM user ;
将输出的name(age)以title字段作为列名。
SELECT name,height*weight AS volume FROM user;
将height和weight相乘,然后以别名volum作为字段输出.
(五)使用函数
- Upper()
SELECT Upper(name) AS upName FROM user;
原有的name就会变成大写,并以upName字段输出。
假如有字段birthday的存储为2015-01-02 10:34:23那么我们仅仅知道她是2015-01-02那天生日,那么该怎么匹配呢?
SELECT name,birthday FROM user WHERE Date(birthday) = '2015-01-02';
因为Date()函数返回日期部分,不返回时间。
(六)汇总数据
SELECT AVG(age) AS avg_age FROM user where address= ‘beijing’;
返回beijing地区的年龄平均值。
SELECT AVG(DISTINCT age) AS avg_age FROM user where address= ‘beijing’;
返回beijing地区的不同年龄(当有多个20时,只取一个用来计算)平均值。
- COUNT()两种用法。一种是COUNT(*),总行数包括NULL行,一种是COUNT(address),只对address非NULL的行数计数。
SELECT COUNT(*) AS num_count FROM user;
- SUM()不仅可以用来计算指定列值的和,还可以用来合计计算值。
(七)分组数据
SELECT address,COUNT(*) AS count_address FROM user GROUP BY address;
返回按照地址分组的,每个地址的总行数。
GROUP BY语句需要在WHERE语句之后,出现在ORDER BY语句之前。
- 过滤分组
SELECT address,COUNT(*) AS count_address FROM user GROUP BY address HAVING COUNT(*)>=2;
返回按照地址分组的,每个地址至少有两行的每个地址的总行数。
- WHERE 与 HAVING的区别
where过滤实在分组之前,HAVING是在分组后过滤。where过滤掉行不在分组中。
SELECT address,COUNT(*) AS count_address FROM user WHERE age >20 GROUP BY address HAVING COUNT(*)>=2;
首先去掉那些年龄小于21的行
然后按照地址分组
最后显示分组中超过两行的
(八) 子查询
将第一次查询的结果,作为第二次查询的where条件。
将用户表中的用户id,作为订单表中的用户id进行总数查询计算,然后显示。
(九) 联结表
联结是利用SQL的SELECT能执行的最重要的操作。
1:简单联结/内部联结/等值联结
假设供应商表只有供应商名称和id,产品表有产品信息及产品对应的供应商id。那么我们想要所有供应商对应的他的产品信息表如下:
SELECT vent_name,prod_name,prod_price FROM vent,product where vent.vent_id=product.vent_id ORDER BY vent_name;
上面的语句也可以转换为
SELECT vernt_name,prod_name,prod_price FROM vent INNER JOIN product ON vent.vent_id=product.vent_id;
当需要同时查阅多个表时,既可以使用子查询,也可以使用联结查询
字段别名是会返回到客户端的,但是表别名则不会
2:自联结
相同表中多次查询可以使用自联结。我们在FROM中使用表别名。假设我们要在同一个产品表中,查看keyboard供应商的其它产品。因为这里要先根据keyboard查处供应商,再根据供应商来查产品表中的其它产品。
SELECT p1.prod_name FROM product AS p1,product AS p2 WHERE p1.vent_id=p2.vent_id AND p2.prod_name='keyboard' ;
3:自然联结
4:外部联结
对每个客户下多少订单进行统计,同时还要包括哪些尚未下过订单的客户。
SELECT custom.cust_id,order.order_num FROM custom LEFT OUTER JOIN order ON custom.cust_id=order.cust_id;
OUT JOIN ,必须使用关键字RIGHT 或LEFT关键字指定包括其所在行的表。左右是以OUT JOIN来划分的。
(十)组合查询
将多个SELECT语句的结果,合并为一个结果返回。多数情况下多个查询语句组合和多个where查询条件完成结果相同。我们可以直接用UNION
关键字将连两个查询语句联合起来。
SELECT name,age,address FROM user WHERE age=20 UNION SELECT name,age,address FROM user WHERE address="beijing";
使用UNION ALL
不会去掉多次查询出现的相同行,否则自动去重。要想排序的话,ORDER BY语句出现在最后一条查询语句后面。
(十一)全文本搜索
常用的引擎如MyISAM支持全文本搜索,但是InnoDB不支持。
创建索引,可以在创建表时创建,也可以在之后修改。
INDEX,FULLTEXT,UNIQUE
SELECT describe FROM user WHERE Match(describe) Against ('love');
Match()可以指定多个列。Against()指定匹配内容。这里是在创建表带时候,就指定了FULLTEXT(describe)建立了索引。
三:插入数据
(一)依赖列的顺序以及列的信息来插入行
这里假定第一列为自增量用户id,第二列住址可以为NULL,第三列姓名,第四列年龄。如果不指定列名,就要把所有列的值都给出。因为第一列是自增的,因此不能指定值。
INSERT INTO user VALUES(NULL,NULL,'xiaguangcheng',25);
(二)安全的INSERT语句,可以不依赖列在表中的顺序指定列名,但是值必须按照指定的列名顺序给出。对于省略的列,要么在表定义中有默认值,要么允许NULL。
INSERT INTO user(name,address,age) VALUES('xiaguangcheng','beijing',25);
(三)降低更新/删除/添加的优先级
因为更新索引耗时,会影响查询语句,所以可以降低其优先级
INSERT LOW_PRIORITY INTO ...
(四)插入多行
插入多行,可以将两条插入语句中间用分号隔开。也可以在列名和次序相同的情况下,使用多个VALUES(),(),();后面的括号来添加。
INSERT INTO user(name,address,age) VALUES('xiaguangcheng','beijing',25),('xiaxuele','china',20);
(五)将旧表数据导入新表
INSERT INTO user(name,address,age) SELECT name,address,age FROM user_old;
上面并没有导入作为自增量的userid,因为要保障userid是唯一的。所以导入新数据,mysql会自动增加。如果能够确保旧表与新表的userid不会重复,那么也可以导入。当然SELECT查询的列名和INSERT INTO插入的列名可以不一样。
四:更新删除数据
(一)更新指定行
UPDATE user SET address='henan' WHERE name='xiaguangcheng';
将用户xiaguangcheng的地址更新为henan。如果没有WHERE就会更新所有列。
UPDATE user SET address='hubei',age=20 WHERE name='xiaguangcheng';
更新多个列用逗号隔开。当更新多个列时,如果某个更新出错,那么这一次操作的所有更新都会取消。如果在更新出错时,想要出错之前的更新也生效,就使用IGNORE
UPDATE IGNORE user...
删除某个列的值,可以将其设置为NULL,如果允许为NULL值的话。
(二)删除数据
- 删除某行
DELETE FROM user WHERE name='xiaguangcheng';
删除某列可以使用UPDATE。如果没有WHERE就会删除所有行。而删除所有行,还可以使用
TRUNCATE TABLE user
上面的语句实际上是删除了原来的表,重新建了一个表。
五:创建和操作表
CREATE TABLE user (
user_id int NOT NULL AUTO_INCREMENT,
name char(50) NOT NULL,
address char(100) NULL,
age int NOT NULL DEFAULT 10,
PRIMARY KEY(user_id)
)ENGINE=InnoDB;
数据库中的表需要手动删除,因此不用担心会覆盖掉。下面的语句是先检查是否有同名表,但不检查结构是否一样。如果没有再创建新表,如果有就不创建。
CREATE TABLE IF NOT EXISTS user (
user_id int NOT NULL AUTO_INCREMENT,
name char(50) NOT NULL,
address char(100) NULL,
age int NOT NULL,
PRIMARY KEY(user_id)
)ENGINE=InnoDB;
- 主键即可以是单列,也可以是多列.不能为NULL值。
PRIMARY KEY(user_id,name)
每个表只能有一个AUTO_INCREMENT列。如果该列被手动插入了一个唯一值,那么后续的增量将开始使用该手工插入的值。
如何获取自动增量的值
SELECT last_insert_id();
返回最后一个AUTO_INCREMENT值。
- 默认值
age int NOT NULL DEFAULT 10
如果没有指定,就会默认为10
- ENGINE 默认引擎,如果不显示指定,会有默认值。
InnoDB支持事务,不支持全文本搜索。
MyISAM支持全文本搜索,不支持事务。
- 更改表
ALTER TABLE user ADD height int NOT NULL DEFAULT 160;
给user表新增一个height字段。
ALTER TABLE user DROP COLUMN height;
删除user表中的height字段。
ALTER常用来定义外键。不过这个语句在sqlite中并不好用。
ALTER TABLE student ADD CONSTRAINT student_id FOREIGN KEY (user_id) REFERENCES user(user_id);
上面的语句中,student_id是约束名称,第一个出现的user_id是student表中的字段,第二个user_id是user表中的字段。
所以在sqlite中定义外键,最好在创建表的时候就指定。而且需要在命令行中打开支持开关。
PRAGMA foreign_keys = ON;
创建:
CREATE TABLE album(
albumartist TEXT,
albumname TEXT,
albumcover BINARY,
PRIMARY KEY(albumartist, albumname)
);
CREATE TABLE song(
songid INTEGER,
songartist TEXT,
songalbum TEXT,
songname TEXT,
FOREIGN KEY(songartist, songalbum) REFERENCES album(albumartist, albumname)
);
复杂表结构更改为了安全起见,一般步骤如下:
1:用希望的所有列创建一个新表
2:使用INSERT SELECT 语句复制内容到新表
3:检验包含所需数据的新表
4:重命名旧表
5:重命名新表
6:根据需要,重新创建触发器,存储过程,索引,外键。
- 删除表
DROP TABLE user;
- 重命名表名
RENAME TABLE user TO new_user;
六:视图
视图能够简化复杂的联结。视图是虚拟表。
- 创建视图使用CREATE VIEW
- 查看创建视图的语句SHOW CREATE VIEW viewname
- 删除视图DROP VIEW viewname
- 更新视图可以先DROP再CREATE。也可以使用CREATE OR REPLACE VIEW
CREATE VIEW virtual_user AS SELECT name,age FROM user,student WHERE user.user_id=student.user_id;
检索20岁还是学生的用户
SELECT name,age FROM virtual_user WHERE age=20;
再比如要显示name(age)
CREATE VIEW temp_user AS SELECT Concat(name,'(',age,')') as temp_title FROM user;
再这个temp_user视图上,查询
SELECT * FROM temp_user;
视图更新收到分组,联结,子查询,并,聚集,DISTINCT等限制,主要用在检索(select)上,而不用于更新(update,insert,delete);
七:使用存储过程
存储过程:就是为以后的使用而保存的一条或者多条有步骤的MySQL语句的集合。简单,安全,高性能。
创建存储过程
CREATE PROCEDURE xyz()
BEGIN
SELECT Avg(age) AS avg_age FROM user;
END;
如果是在命令行中执行上面这段语句会出错,需要修改为
DELIMITER //
CREATE PROCEDURE xyz()
BEGIN
SELECT Avg(age) AS avg_age FROM user;
END //
DELIMITER ;
调用上面的存储过程
CALL xyz();
删除上面的存储过程
DROP PROCEDURE xyz;
删除的时候不需要括号。
上面这个例子是不使用参数的存储过程,还有使用参数的存储过程,略复杂。
八:使用游标
游标(cursor)是一个存储在MySQL服务器上的数据库查询, 它不是一条SELECT语句,而是被该语句检索出来的结果集。不像多数DBMS,MySQL游标只能用于 存储过程(和函数)。
CREATE PROCEDURE xyz()
BEGIN
DECLARE abc CURSOR
FOR
SELECT name FROM user;
END;
DECLARE定义了一个abc的游标。使用游标需要
OPEN abc;
关闭游标
CLOSE abc;
当游标打开之后可以使用FETCH语句分别访问他的每一行。
九:触发器
当某个表发生更改时自动处理。创建触发器
- 唯一的触发器名
- 触发器关联的表
- 响应的活动(DELETE,INSERT,UPDATE)
- 何时执行活动
CREATE TRIGGER newuser AFTER INSERT ON user FOR EACH ROW SELECT 'user add';
触发器仅支持表,不支持视图和临时表。每个表最多支持六个触发器,之前之后的插入,更新和删除。所以六个。
删除触发器
DROP TRIGGER newuser;
例子
CREATE TRIGGER newuser AFTER INSERT ON user FOR EACH ROW SELECT NEW.user_id;
每次插入一个用户,都会返回插入用户的自增id。假设user_id是自增的。这里面的NEW虚拟表是系统维护的,不用操心。
例子
将删除的行保存到一个存档表中
CREATE TRIGGER deleteuser BEFORE DELETE ON user FOR EACH ROW
BEGIN
INSERT INTO archive_user(user_id,name,address,age) VALUES(OLD.user_id,OLD.name,OLD.address,OLD.age);
END;
其中archive_user是存档表。OLD是系统维护的虚拟表。
当我们使用UPDATE触发器时
- 可以使用OLD访问更新之前的值,使用NEW访问更新之后的值。
CREATE TRIGGER updateuser BEFORE UPDATE ON user FOR EACH ROW SET NEW.name=Upper(NEW.name);
每次更新的时候,名字都是大写。
十:事务管理
transaction 一组sql语句
rollback 撤销指定sql语句
commit 将未存储的sql语句结果写入数据库表
savepoint 事务中的临时占位符,可以对它发布会退。
开始事务
START TRANSACTION;
事务不能回退SELECT语句,也不能回退CREATE或者DROP操作。
SELECT * FROM user;
START TRANSACTION;
DELETE FROM user;
SELECT * FROM user;
ROLLBACK;
SELECT * FROM user;
1:显示user表非空
2:开启事务
3:删除user表所有行
4:显示user表已经为空
5:回退事务
6:显示user表非空
事务要么被显示提交关闭,要么被回退关闭。
START TRANSACTION;
DELETE FROM user WHERE user_id=100;
DELETE FROM student WHERE user_id=100;
COMMIT;
如果第二条delete没有执行成功,那么第一条也会被自动撤销。否则两条都执行成功,就提交。
- 部分回退使用savepoint。
START TRANSACTION;
DELETE FROM user WHERE user_id=100;
SAVEPOINT delete1;
DELETE FROM student WHERE user_id=100;
SAVEPOINT delete2;
DELETE FROM student1 WHERE user_id=100;
ROLLBACK TO delete1;
当三行都正确删除之后,回退到指定点delete1;那么user表就回保存完好。
十一:全球化
SHOW CHARACTER SET;
显示可用字符集。
SHOW COLLATION;
显示完整字符集。
SELECT * FROM user ORDER BY name COLLATE latin1_general_cs;
使用COLLATE指定一个备用的校对顺序。
十二:访问控制
为不同的用户,设置不同的操作权限。MySQL上的所有用户被保存在一个名为mysql的数据库中
use mysql;
SELECT user FROM user;
即可查看所有的用户。
- 创建一个用户,这里给了密码,也可以不设置密码。
CREATE USER xia IDENTIFIED BY 'xiapassword';
- 重命名一个用户
RENAME USER xia TO xiaguangcheng;
- 删除一个用户
DROP USER xiaguangcheng;
- 查看用户权限
SHOW GRANTS FOR xiaguangcheng;
权限用用户名和主机名结合定义。
- 更改权限
GRANT SELECT ON school.* TO xia;
给用户xia在school数据库中所有表的SELECT查询权限。
- 撤销权限
REVOKE SELECT,INSERT ON school.* FROM xia;
权限包括:
整个服务器中所有数据库
整个数据库中所有表
整个表
指定列
指定存储过程
更改用户密码
SET PASSWORD FOR xia=Password('abc23rdf&4');
优化
- 优化查询语句,实验联结,并,子查询等。
- 使用EXPLAIN让mysql解释它如何执行一跳查询语句。
- 一般来说,存储过程要比一条一条执行要快。
- 尽量不要使用通配符*
- 在导入数据时,关闭自动体检。导入数据后,再建立索引。
- or条件太多,可以用多条select语句用union连接。
- fulltext替换like
MySQL数据类型
附
adb root //确保当前打开的模拟器是以root身份打开的。
cd /data/user/0/packageName/databases // 进入databases目录就可以ls,查看dbName了。
sqlite3 dbName.db //打开dbName.db数据库。
.table //可以列出打开的这个数据库的所有表名。
pragma table_info(tableName) // 可以查看表结构
.schema tableName //可以查看建表语句
select * from sqlite_master; //由于每个数据库都有一个sqlite_master表用来保存建表信息。因此可以查看所有表的创建信息。
.header on // 输出时附带列名
.timer on //输出时附带cpu执行时间
.mode column // 左对齐输出
.quit // 退出