现在的位置: 首页 > 综合 > 正文

第十七天:sql入门

2018年05月17日 ⁄ 综合 ⁄ 共 9915字 ⁄ 字号 评论关闭

Mysql的并发连接数,基本50-60个都是非常大的了,在同一时刻有50-60个人同时访问了库,那么这个网站至少有2万人。

l  表的一行称之为一条记录

l  表中一条记录对应一个java对象的数据

sql(structured query lanaguage) 结构化查询语言

 

创建一个名称为mydb1的数据库

create database mydb1;

 

显示所有数据库

show databases;

 

创建一个使用utf-8字符集的mydb2数据库。

create database mydb2 character set utf8;//很让人郁闷,mysql里面没有-

 

创建一个使用utf-8字符集,并带校对规则的mydb3数据库(在mysql文档里面寻找)

create database mydb3 character set utf8collate
utf8_general_ci;

 

查看前面创建的mydb2数据库的定义信息

show create databasemydb2;

 

删除前面创建的mydb1数据库

drop database mydb1;

 

 

查看服务器中的数据库,并把mydb2库的字符集修改为gb2312;(但是不能够更改库名)

alter database mydb2character set gb2312;

 

备份mydb3库中的数据,并恢复(恢复的是数据库里面的表,而不是数据库,所以你要先把数据库创建好以后,再恢复,用source是基于要先新建数据库的,而我自己用的那个不用先建立数据库

1.准备数据并备份

use mydb3;

create table test

(

       idint

);

insert into test(id) values(1);

备份(退到window命令行窗口):mysqldump -u root -p mydb3>c:\test.sql

 

2.恢复:

mysql -uroot -p

create database mydb3;

use mydb3;

source c:\test.sql

 

分类

数据类型

说明

数值类型

BIT(M)

TINYINT [UNSIGNED] [ZEROFILL]

BOOL,BOOLEAN

SMALLINT [UNSIGNED] [ZEROFILL]

INT [UNSIGNED] [ZEROFILL]

BIGINT [UNSIGNED] [ZEROFILL]

FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]

DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]

位类型。M指定位数,默认值1,范围1-64

带符号的范围是-128到127。无符号0到255。

使用0或1表示真或假

2的16次方

2的32次方

2的64次方

M指定显示长度,d指定小数位数

表示比float精度更大的小数

文本、二进制类型

CHAR(size) char(20)

VARCHAR(size)  varchar(20)

BLOB   LONGBLOB

TEXT(clob)          LONGTEXT(longclob)

固定长度字符串

可变长度字符串

二进制数据

大文本

时间日期

DATE/DATETIME/TimeStamp

Date 只能存日期,

DateTime日期和时间

日期类型(YYYY-MM-DD)  (YYYY-MM-DD HH:MM:SS),TimeStamp表示时间戳,它可用于自动记录insert、update操作的时间

 

创建一个员工表

create table employee

(

       idint,

       namevarchar(20),

       sexvarchar(4),

       birthdaydate,

       entry_datedate,

       jobvarchar(100),

       salarydouble,

       resumetext  //最后一个字段后面不能够跟分号。非常恶心。

)character set utf8 collateutf8_general_ci;

 

在上面员工表的基本上增加一个image列。(它肯定是一个二进制的数据列)

alter table employee addimage blob;

 

查看表

desc employee;

 

修改job列,使其长度为60。

alter table employee modify jobvarchar(60);

 

删除sex列

alter table employee drop sex;

 

表名改为user

rename table employee to user;

 

修改表的字符集为utf-8

alter table user character set utf8;

 

查看表的字符集

show create table user;(表的创建语句)

 

列名name修改为username

alter table user change column name usernamevarchar(20);

 

使用insert语句向表中插入三个员工的信息。

rename table user to employee;

insert intoemployee(id,username,birthday,entry_date,job,salary,resume)values(1,'aaa','1980-09-09','1980-09-09','bbb',90,'aaaa');

insert intoemployee(id,username,birthday,entry_date,job,salary,resume)values(2,'bbb','1980-09-09','1980-09-09','bbb',90,'aaaa');

查看插入的数据

select * from employee;

 

varchar(20)表示20个字符,一个汉字是一个字符。因为这个表的编码是UTF-8所以才是UTF-8.

不能插入中文:

第一、   该列长度够不够

第二、   表的编码

第三、   Mysql的乱码问题,在命令行输入中文,交过来的汉字会用GB2312编码,但是表在保存的时间用的是UTF-8.因为数据库认为我是UTF-8它也以为传过来的是UTF-8,所以我们只要告诉数据库传过来的是GB2312.那么让它自己转为UTF-8以后再保存。

插入中文数据

insert into employee(id,username)values(2,'小李子');

show variables like 'chara%';

set character_set_cilent=gb2312;

insert into employee(id,username)values(2,'小李子');

查询时如果发生乱码:(因为在显示的时间是按照GB2312的编码显示的,而我们存储的却是按照UTF-8存储的,所以我们仍然告诉命令行你把数据弄出来的把UTF-8转换成GB2312的编码以后你再传给我)

set character_set_results=gb2312;

select * from employee;

 

 

将所有员工薪水修改为5000元。

update employee set salary=5000;

 

将姓名为’aaa’的员工薪水修改为3000元。

update employee set salary=3000 whereusername='aaa';

 

将姓名为’aaa’的员工薪水修改为4000元,job改为ccc。

update employee set salary=4000,job='ccc'where username='aaa';

 

mysql中只要是字符串都是有单引号的。

 

在写更新的时间先把where条件语句写出来。

 

将aaa的薪水在原有基础上增加1000元 。    

update employee set salary=salary+1000where username='aaa';

 

 

delete:

如果不使用where子句,将删除表中所有数据。

Delete语句不能删除某一列的值(可使用update

使用delete语句仅删除记录,不删除表本身。如要删除表,使用drop table语句。

insertupdate一样,从一个表中删除记录将引起其它表的参照完整性问题,在修改数据库数据时,头脑中应该始终不要忘记这个潜在的问题。也就是说,如果存在关联关系,先要取消关系再删除

 

删除表中名称为’zs’的记录

delete from employee where username='aaa';

 

删除表中所有记录。

delete from employee;

 

使用truncate删除表中记录(它是删除整个表,然后重建表结构。)

truncate table employee

 

执行sql脚本

source c:\student.sql

 

查询表中所有学生的信息。

select * from student;

 

查询表中所有学生的姓名和对应的英语成绩。

select name,english from student;

 

过滤表中重复数据。

select distinct english from student;

 

在所有学生总分上加10分特长分。

selectname,(english+chinese+math)+10 from student;

说明sql可以完成一些简单的业务逻辑处理。

 

 

使用别名表示学生分数。

select name as 姓名,(english+chinese+math)+10 as 总分 from student;

select name 姓名,(english+chinese+math)+10 总分 from student;

 

查询姓名为wu的学生成绩

select * from student where name='王五'

 

查询英语成绩大于90分的同学

select name from student whereenglish>90;

 

查询总分大于200分的所有同学

select name from student where(english+chinese+math)>200;

 

查询英语分数在 80-90之间的同学

select name from student whereenglish>80 and english<90;

select name from student where englishbetween 80 and 90;

 

查询数学分数为89,90,91的同学

select * from student where math=80 ormath=90 or math=91;

select * from student where mathin(80,90,91);

 

查询所有姓李的学生成绩。

select * from student where name like '李%'

 

查询数学分>80,语文分>80的同学。

select name from student where math>80and chinese>80;

 

l  Order by 指定排序的列,排序的列即可是表中的列名,也可以是select 语句后指定的列名。

l  Asc 升序、Desc 降序

l  ORDER BY 子句应位于SELECT语句的结尾。

 

对数学成绩排序后输出

select * from student order by math;

 

对总分排序后输出,然后再按从高到低的顺序输出

select * from student order by(math+english+chinese) desc;

 

对姓李的学生成绩排序输出

select * from student where name like '李%' order by (math+english+chinese);

 

统计一个班级共有多少学生?

select count(*) from student;

 

 select count(math)from stu_info;(它只统计含有有效数据的行)

 

统计数学成绩大于90的学生有多少个?

select count(*) from student wheremath>90;

 

统计总分大于250的人数有多少?

select count(*) from student where(math+english+chinese)>250;

 

统计一个班级数学总成绩?

select sum(math) from student;

 

统计一个班级语文、英语、数学各科的总成绩(不要少了分号)

select sum(chinese),sum(english),sum(math) from student;

 

统计一个班级语文、英语、数学的成绩总和

select sum(chinese+math+english) fromstudent;

 

统计一个班级语文成绩平均分(不要用count(*)可能有的数据为空例如缺考)

select sum(chinese)/count(chinese) from student;

 

求一个班级数学平均分?

select avg(math) from student;

 

求一个班级总分平均分

select avg(math+english+chinese) fromstudent;

 

求班级最高分和最低分

select max(math+english+chinese),min(math+english+chinese)from student;

 

第6种形式的select:

create table orders(

       idint,

       productvarchar(20),

       pricefloat

);

 

insert into orders(id,product,price) values(1,'电视',900);

insert into orders(id,product,price)values(2,'洗衣机',100);

insert into orders(id,product,price)values(3,'洗衣粉',90);

insert into orders(id,product,price)values(4,'桔子',9);

insert into orders(id,product,price)values(5,'洗衣粉',90);

使用group by
子句对列进行分组(把相同的归成一类)

使用having
子句过滤

Havingwhere均可实现过滤,但在having可以使用合计函数,having通常跟在group
by
后,它作用于组。

Where子句后面不能使用全计函数(如count  sum)

对订单表中商品归类后,显示每一类商品的总价

select product,sum(price) from orders group by product;

 

 

查询购买了几类商品,并且每类总价大于100的商品

select product from orders group by productwhere sum(price)>100;×

select product from orders group by product havingsum(price)>100;

 

 

主键约束

create table test1

(

       idint primary key,

       namevarchar(20)

);

 

主键自动增长:

create table test2

(

       idint primary key auto_increment,

       namevarchar(20)

);

 

唯一约束和非空约束

Create table user(

       Idvarchar(40),

)

create table user

(

       id int primary keyauto_increment,//这种方法只有菜鸟才这么做。高手用uuid.

       usernamevarchar(40) not null unique,

       passwordvarchar(40) not null,

       email varchar(100) not null unique//不能为空,并且唯一

);

 

外键约束

create table male

(

       idint primary key auto_increment,

       namevarchar(40)

);

 

create table female

(

       idint primary key auto_increment,

       namevarchar(40),

       male_idint,

       constraintmale_id_FK foreign key(male_id) references male(id)

);

 

类中:

 

Department

String id

String name

Set employees=new HashSet()

Employee

String id;

String name;

double salary;

Deparement department

 

在类里面肯定要用面向对象的思维来写,在对应这两个类创建sql语句的时间,要根据一对多,多对一,外键关系去写,十分重要,平时我们用hibernate自动生成的,不用去管太多,这对我们非常不好。

创建部门表和员工表(一对多或多对一)

create table department

(

       idint primary key auto_increment,

       namevarchar(100)

);

 

create table employee

(

       idint primary key auto_increment,

       namevarchar(100),

       salarydouble,

       department_idint,

       constraintdepartment_id_FK foreign key(department_id) references department(id)

);

 

原则:一个实体创建一张表,不要管其它。

@JoinColumn当前实体的外键参考注释这个对象的主键。

这样就实现了上面类中的面向对象,而在表中却是按照外键关联的。

@ManyToOne

       @JoinColumn(name="user_id")

       public UsergetUser() {

              returnuser;

       }

 

创建学生、老师表(多对多)

create table teacher

(

       idint primary key auto_increment,

       namevarchar(100),

       salarydouble

);

 

create table student

(

       idint primary key auto_increment,

       namevarchar(100)

);

 

create table teacher_student

(

       teacher_idint,

       student_idint,

       primarykey(teacher_id,student_id),

       constraint teacher_id_FK foreign key(teacher_id) referencesteacher(id),

       constraint student_id_FK foreign key(student_id) referencesstudent(id)

);

 

insert into teacher(name,salary) values('老王',1000);

insert into teacher(name,salary) values('老李',1000);

 

insert into student(name) values('aaa');

insert into student(name) values('bbb');

insert into student(name) values('ccc');

 

insert intoteacher_student(teacher_id,student_id) values(1,1);

insert intoteacher_student(teacher_id,student_id) values(1,2);

insert into teacher_student(teacher_id,student_id)values(1,3);

 

insert intoteacher_student(teacher_id,student_id) values(2,1);

 

已知老师的id为1,查询出1号老师所有的学生

select s.* fromteacher_student t_s,student s where teacher_id=1 and t_s.student_id=s.id;

 

1号学生有几个老师(多表查询,自己想成两个表通过相同的部门连接在一起。

select teacher.* fromteacher_student,teacher where student_id=1 andteacher_student.teacher_id=teacher.id;

 

 

创建人、身份证表(一对一)

create table person

(

       idint primary key auto_increment,

       namevarchar(30)

);

 

create table idcard

(

       idint primary key,

       numvarchar(30) not null unique,

       constraintperson_id_FK foreign key(id) references person(id)

)

 

 

 

SQLtruncate tabledelete的区别

TRUNCATETABLE 在功能上与不带Where
子句的 Delete
语句相同:二者均删除表中的全部行。但 TRUNCATE TABLE
Delete
速度快,且使用的系统和事务日志资源少。 

Delete 语句每次删除一行,并在事务日志中为所删除的每行记录一项。TRUNCATE TABLE
通过释放存储表数据所用的数据页来删除数据,并且只在事务日志中记录页的释放。 

TRUNCATE TABLE 删除表中的所有行,但表结构及其列、约束、索引等保持不变。新行标识所用的计数值重置为该列的种子。如果想保留标识计数值,请改用 Delete 

对于由 FOREIGN KEY
约束引用的表,不能使用 TRUNCATE TABLE,而应使用不带 Where
子句的 Delete
语句。由于 TRUNCATE TABLE
不记录在日志中,所以它不能激活触发器。 

TRUNCATE TABLE 不能用于参与了索引视图的表。 

truncate,delete,drop的异同点:  
注意:这里说的delete是指不带where子句的delete语句 
 
 
相同点:truncate和不带where子句的delete,
以及drop都会删除表内的数据  

不同点 
1.truncate
delete只删除数据不删除表的结构(定义 
  drop
语句将删除表的结构被依赖的约束(constrain),触发器(trigger),索引(index);
依赖于该表的存储过程/函数将保留,但是变为invalid状态. 
 
 
2.delete语句是dml,这个操作会放到rollback segement,事务提交之后才生效;如果有相应的trigger,执行的时候将被触发 
  truncate,drop
ddl,
操作立即生效,原数据不放到rollback segment,不能回滚.
操作不触发trigger. 

3.delete语句不影响表所占用的extent,
高水线(high w2atermark)保持原位置不动  
  
显然drop语句将表所占用的空间全部释放  
   truncate
语句缺省情况下将空间释放到 minextents extent,除非使用reuse
storage;   truncate
会将高水线复位(回到最开始). 

4.速度,一般来说: drop> truncate > delete 

5.安全性:小心使用drop
truncate,尤其没有备份的时候.否则哭都来不及 

使用上: 
想删除部分数据行用delete,注意带上where子句.
回滚段要足够大. 

想删除表,当然用drop 

想保留表而将所有数据删除.
如果和事务无关,truncate即可.
如果和事务有关,或者想触发trigger,还是用delete. 

如果是整理表内部的碎片,可以用truncate跟上reuse stroage,再重新导入/插入数据;

抱歉!评论已关闭.