MySQL数据库:SQL语句基础、库操作、表操作、数据类型、约束条件、表之间的关系...

数据库相关概念:

  1. 数据库服务器:运行数据库管理软件的计算机

  2. 数据库管理软件:MySQL、Oracle、db2、slqserver

  3. 库:文件夹,用来组织文件/表

  4. 表:文件(类似于excel),用来存放多行内容/多条记录

  5. 记录:事物一系列典型的特征

  6. 数据:描述事物特征的符号

MySQL数据库就是一个套接字软件,用来管理其他机器上的数据文件

MySQL介绍:

MySQL是一个关系型数据库管理系统;就是一个基于socket编写的C/S架构的软件

客户端软件

  mysql自带:如mysql命令,mysqldump命令等

  python模块:如pymysql

数据库管理软件分类:

分两大类:

  关系型:如 sqllite,db2,oracle,access,sql server,mysql,注意:sql语句通用

  非关系型:mongodb,redis,memcache

可以简单的理解为:

  关系型数据库需要有表结构

  非关系型数据库是key-value存储的,没有表结构

 

SQL语句基本操作:

MySQL服务端软件即mysqld帮我们管理好文件夹及文件,前提是作为使用者的我们,需要下载mysql的客户端,或者其他模块来连接到mysqld,然后使用mysql软件规定的语法格式去提交自己的命令,实现对文件夹或文件的管理。该语句即sql(Structured Query Language 结构化查询语言)

SQL语言主要用于存取数据、查询数据、更新数据和管理关系数据库系统;分为3种类型:

1. DDL语句:  数据库定义语言:数据库、表、视图、索引、存储过程,例如create,drop,alter

2. DML语句:  数据库操作语言:插入数据insert、删除数据delete、更新数据update、查询数据select

3. DCL语句:  数据库控制语言:例如控制用户的访问权限grant、revoke 

操作文件夹(库)

增: create database db1 charset utf8;     (创建数据库db1,其字符编码为UTF-8;db1是库名)

查: show create database db1;    (查看我刚创建的文件夹db1)
   show databases;    (查看所有的数据库)

改: alter database db1 charset gbk; (改数据库 db1 的字符编码 为 gbk; 不能改名字,只能改字符编码)

删: drop database db1;   (删数据库db1)

操作文件(表)

先切换文件夹: use db1;   (切换到数据库db1) 

查看当前所在的文件夹(库): select database(); 

增: create table t1(id int,name char(10));  (创建文件(表),文件名是t1,表中字段是id(id的数据类型是整型) 和 name(name是字符))

查: show create table t1;  (查看创建的文件t1)
     desc t1;   (查看表t1;desc是describe的缩写)
   show tables;  (查看当前库下所有的表/文件)

改: alter table t1 modify name char(6);    (修改表t1,把t1中name字段char的宽度改为6)
   alter table t1 change name NAME char(7);   (修改表t1,把t1中name字段改为NAME,并把char改为7)
   alter table t1 alter column name set default "NEO"; -- 修改默认值
删:
drop table t1; (删除t1这个表)

操作文件内容(记录)

增:insert t1(id,name) values(1,"neo1"),(2,"neo2"),(3,"neo3");    (往t1这个文件中插入values;插入多条value用逗号隔开;values中的值按照t1后面的字段顺序添加)
  insert t1 values(1,"neo1"),(2,"neo2"),(3,"neo3");   (t1后面不加字段名,默认按字段顺序添加values)

查:select id,name from t1;    (查看当前库下t1这个表的id和name)
  select id,name from db1.t1;   (如果所查看的t1表不在当前库下,则在t1前加上db1这个库名前缀)
  select id from t1;  (只查询id)
  select * from t1;   (查询所有字段)

改:update db1.t1 set name="NEO";  (更改db1库下的t1表,把name字段全部设置成NEO)
  update t1 set name="Neo" where id=2;   (更新当前库下的t1表,把id为2那一行name设置成Neo)

删:delete from t1;  (把t1表下的所有记录都删除)
     delete from t1 where id=2;   (把t1表下id为2的记录删除)

 

库操作:

系统数据库:

  information_schema:虚拟库,不占用磁盘空间,存储的是数据库启动后的一些参数,如用户表信息、列信息、权限信息、字符信息等

  performance_schema:MySQL 5.5开始新增一个数据库:主要用于收集数据库服务器性能参数,记录处理查询请求时发生的各种事件、锁等现象

  mysql:授权库,主要存储系统用户胡权限信息

  test:MySQL数据库系统自动创建的测试数据库

创建数据库:

1. 语法: 
    create database 数据库名 charset utf8;

2. 数据库命名规则:

  可以由字母、数字、下划线、@、#、¥

  区分大小写

  唯一性

  不能使用关键字如create、select等

  不能单独使用数字

  最长128位

数据库相关操作:

查看数据库:
  show databases;
  show create database db1;
  select database();

选择数据库:
  use 数据库名;

删除数据库:
  drop database 数据库名;

修改数据库:
  alter database db1 charset utf8;

 

存储引擎介绍:

1. 数据库中的表有不同胡类型,表的类型不同,会对应mysql不同的存取机制,表类型又称存储引擎;存储引擎就是表的类型

2. 查看MySQL支持的存储引擎: show engines;   # 默认的存储引擎是innodb

3. 指定表类型/存储引擎:

  create table t1(id int)engine=innodb;

  create table t1(id int)engine=memory;

  create table t1(id int)engine=blackhole;

 

表操作:

1. 表介绍:表相当于文件,表中的一条记录就相当于文件的一行内容,不同的是,表中的一条记录有对应的标题,称为表的字段

id,name,age,sex称为字段,其余的,一行内容称为一条记录

2. 创建表:

-- 语法:

  create table 表名(

  字段名1 类型[(宽带)约束条件],

  字段名2 类型[(宽带)约束条件],

  字段名3 类型[(宽带)约束条件]

  ) ;

-- 附:表中最后一个字段后面不要再加逗号

注意:

  1. 同一张表种,字段名不能相同

  2. 宽带和约束条件可选

  3. 字段名肯类型椒必须的

3. 查看表结构:

1.  describe 表名;    -- 查看表结构,可简写为  desc 表名;
2.  show create table 表名;  -- 查看表详细结构,可加 \G

4. 修改表结构:

1. 修改表名: alter table 表名 rename 新表名;

2. 增加字段: alter table 表名 add 字段名 数据类型 [完整性约束条件], add 字段名 数据类型 [完整性约束条件];
       alter table 表名 add 字段名 数据类型 [完整性约束条件] first;     -- 把这个字段放到第几个位置
       alter table 表名 add 字段名 数据类型 [完整性约束条件] after 字段名;   -- 把新添加的字段放到某个字段后面

3. 删除字段: alter table 表名 drop 字段名;
4. 修改字段: alter table 表名 modify 字段名 数据类型 [完整性约束条件];   -- 修改字段的数据类型相关信息
       alter table 表名 change 旧字段名 新字段名 新/旧数据类型 [完整性约束条件];   -- 修改字段名和数据类型

5. 删除表: 

drop table 表名;

6. 复制表:

  1. 复制表结构和记录: 

create table 表名1 select name,age from db1.表名2;      -- 数据库db1中的表名2中的name和age复制到表名1中(把表2的查询结果当作复制的内容传给表1)

  2. 只复制表结构,不复制纪录:

create table 表名1 select name,age from db1.表名2 where 1>5;   --   where 1>5是一个假条件(没有纪录能满足这个条件),但表名2的表结构却是存在的,通过这种方式去只复制表结构

  3. 只复制全部的表结构: 

create table 表名1 like db1.表名2;   --  复制db1数据库中表名2的所有表结构,不复制纪录

 

 

数据类型:

存储引擎决定了表的类型,而表内存放的数据也要有不同的类型,每种数据类型都有自己的宽带,但宽度是可选的

详细参考:

    http://www.runoob.com/mysql/mysql-data-types.html

    https://dev.mysql.com/doc/refman/5.7/en/data-type-overview.html

MySQL常用数据类型:

  1. 数字

    整形:tinyint, int, bigint

    小数:

      float:在位数比较短的情况下不精确

      double:在位数比较长的情况下不精确

      decimal:精确,内部原理是字符串形式存储

  2. 字符串:

    char(10):简单粗暴,浪费空间,存取速度快;root存成root000000

    varchar:精确,节省空间,存取速度慢

  3. 时间类型: 最常用:datetime

  4. 枚举类型于集合类型

数值类型:

1. 整数类型:tinyint, smallint, mediumint,bigint; 作用:存储年龄、等级、id、各种号码等

  tinyint[(m)] [unsigned] [zerofill]

  小整数,数据类型用于保存一些范围的整数数值范围:

  有符号: -128~127 ;  无符号: 0~255 ; ps: MySQL中无布尔值,使用tinyint(1)构造

  int[(m)] [unsigned] [zerofill]

  整数,数据类型用于保存一些范围的整数数值范围:

  有符号:-2147483648 ~ 2147483647;无符号: 0 ~ 4294967295

注意:为整数类型指定宽度时,仅仅只是指定查询结果的显示宽度,与存储范围无关;其实我们完全没必要为整数类型指定显示宽带,使用默认的就可以了;默认的显示宽带,都是在最大值的基础上加1

int的存储宽度是4个bytes,即32个bit,即2**32; 无符号最大值为:4294967296-1;有符号最大值:2147483648-1

有符号和无符号的最大数字需要的显示宽度均为10,而针对有符号的最小值则需要11位才能显示完整,所以int类型默认的显示宽带为11是非常合理的;所以,整形类型,没有必要指定显示宽度,使用默认的就行

浮点型:定点数类型:decimal(等同于dec); 浮点类型:float,double;作用:存储薪资、身高、体重、体质参数等

  float[(m,d)] [unsigned] [zerofill]:

    定义:单精度浮点数(非准确小数值),m是数字总个数,d是小数点后个数;m最大值为255,d最大值为30;随着小数的增多,精度变得不准确

  double[(m,d)]  [unsigned] [zerofill]:

    定义:双精度浮点数(非准确小数值),m是数字总个数,d是小数点后个数。m最大值为255,d最大值为30;随着小数的增多,精度比float要高,但也会变得不准确

  decimal[(m[,d])] [unsigned] [zerofill]:

    定义: 准确的小数值,m是数字总个数(符号不算),d是小数点后个数。 m最大值为65,d最大值为30;随着小数的增多,精度始终准确;对于精确数值计算时需要用此类型;decaimal能够存储精确值的原因在于其内部按照字符串存储。

补充知识点:加入一条sql语句写错了,可以利用 \c 来终止这条语句的运行; 假如少了一个引号,就先把引号补全再用\c, 如: '\c

 

日期类型:year, date, time, datetime, timestamp;作用:存储用户注册时间、文章发布时间、入职时间、出生时间、过期时间等

形式与范围:

  year:YYYY(1901/2155)

  date:YYYY-MM-DD (1000-01-01/9999-12-31)

  time:HH:MM:SS('-838:59:59'/'838:59:59')

  datetime: YYYY-MM-DD HH:MM:SS(1000-01-01 00:00:00/9999-12-31 23:59:59 )

  timestamp:YYYYMMDD HHMMSS(1970-01-01 00:00:00/2037 年某时)

先看下面一段sql语句:

 create table stu1(
                   id int,
                   name char(6),
                   born_year year,
                   birth_date date,
                   class_time time,
                   regis_time datetime
                   );   # char(6)是最多能存储6个字符,所以名字最多6个字符

 insert stu1 values(1,"neo",now(),now(),now(),now()); # now()是mysql是自带的一个函数,调用当前时间

执行结果如下:

也可以自己添加日期: 

insert stu1 values(2,"alex","2007","2007-1-11","08:00:00","2016-1-11 11:11:00"); 

如下图:

 

字符类型:

char和varchar括号内的参数指的都是字符的长度

char类型:定长,简单粗暴,浪费空间,存取速度快

  字符长度范围:0-255 (一个中文是一个字符,是utf8编码的3个字节)

  存储:存储char类型的值时,会往右填充空格来满足长度,例如:指定长度为10,存<10个字符则用空格填充直到凑够10个字符存储

  检索:在检索或者说查询时,查出的结构会自动删除尾部的空格,除非我们打开pad_char_to_full_length SQL 模式(SET sql_mode = "PAD_CHAR_TO_FULL_LENGTH";)

varchar类型:变长,精准,节省空间,存取速度慢

  字符长度范围:0-65535(mysql行最大限制为65535字节)

  存储:varchar类型存储数据的真实内容,不会用空格填充;

     varchar类型会在真实数据前加1~2个bytes作为前缀,该前缀用来表示真实数据的bytes字节数(1~2bytes最大表示65535个数字,正好符合mysql对row的最大字节限制,即已经足够使用)

     如果真实的数据<255则需要一个bytes的前缀(1Bytes=8bit 2**8最大表示的数字为255)

     如果真实的数据>255bytes则需要2Bytes的前缀(2Bytes=16bit 2**16最大表示的数字为65535)

  检索: 尾部有空格会保存下来,在检索或者说查询时,也会正常显示包含空格在内的内容

# length:查看字节数;  char_length:查看字符数

1. char填充空格来满足固定长度,但是在查询时会自动删除尾部的空格来匹配查询值

2. 虽然char和varchar的存储方式不太相同,但是取的时候(“=” 的情况),对于两个字符串的比较,都是只比较其值,忽略char存在的右填充(只会忽略后面的空格,不会忽略前面和中间的空格),即使将sql_mode设置成PAD_CHAR_TO_FULL_LENGTH也一样;但这不适用于like

所以,虽然varchar使用起来比较灵活,但是从整个系统的性能角度来说,char数据类型的处理速度更快

枚举类型和集合类型:

字段的值只能在给定范围内选择,如单选框、多选框

enum 单选 只能在给定的范围内选一个值,如性别 sex male/female

set 多选  在给定的范围内可以选择一个或多个值(爱好1,爱好2.。。)

create table client(name char(20),
                    age int,
                    sex enum("female","male"),
                    level enum("vip1","vip2","vip3"),
                    hobbies set("reading","working out","music","run")
                    );

insert client values("neo",18,"male","vip1","music,run"),
                    ("alex",73,"female","vip3","boy");  -- 第二条数据加不进去

运行结果:

 

约束条件:

not null和default:

create table condition_null_default(
                                    id int,
                                    name char(10),
                                    sex enum("male","female") not null default "male"
                                    );

insert condition_null_default(id,name) values(1,"neo"),
                                             (2,"alina","female");

 

如下:

 

约束条件 unique key:

单列唯一:

方式一:

create table department1(
id int unique,
name char(10) unique
);

insert department1 values(1,"IT"),(2,"Sales);

方式二:

create table department2(
id int,
name char(10),
unique(id),
unique(name)
);

联合唯一:

create table server(
id int unique,
ip char(15),
port int,
unique(ip,port)
);    # unique(ip,port)的含义是: ip和port拼到一起后必须是唯一的

 

 

primary key: 

约束:not null unique(不为空且唯一)

存储引擎(默认innodb):对于innodb存储引擎来说,一张表内必须有一个主键(通常将id字段设为主键)

单列主键:

create table t_primary(
id int primary key,name char(16));

对于innodb,如果你不指定主键,innodb会找一个不为空且唯一的字段作为主键;如果没找到,就用它自己隐藏的字段作为主键;如下

复合主键:

create table t_union_primary(
ip char(15),
port int,
primary key(ip,port)
);    # ip和port联合组成主键

 

auto_increment: (自增长)

create table t_auto_incre(
id int primary key auto_increment,
name char(16));   # auto_increment的字段需要指定key  # 默认是从1开始,每次增加1

insert t_auto_incre(name) values("neo"),
("egon"),
("alex");

如果中间自己不按顺序插入了id,后面的id auto_increment时以你新插入的id作为起点

insert t_auto_incre(id,name) values(7,"neo1");

insert t_auto_incre(name) values
("NEO1"),
("NEO2"),
("NEO3");

# 查看mysql关于auto_increment的默认设置
show variables like "auto_inc%";      # show variables 是查看变量,like是模糊匹配,%代表任意长度的任意字符

  # 步长: auto_increment_increment默认为1

  # 起始偏移量(位置): auto_increment_offset默认为1

#设置步长:
set session auto_increment_increment=5;
set global auto_increment_increment=5;

#session是会话级别的修改,就是只在本次运行时有效,退出再登录后会恢复到原先的设置;
#global是全局级别的修改,长期有效,但需要推出后重新登录mysql才会生效

#设置起始偏移量:
set session auto_increment_offset=3;
set global auto_increment_offset=3;
#用法同上;需要注意的一点:起始偏移量必须要小于等于步长

 清空表:

  delete from 表名 where xxx; 不要用delete去清空表,delete用在跟where语句连用的情况下;delete from 表名 无法删除自增长(auto_increment)的纪录

  truncate 表名;  清空表应该用 truncate(能把自增长的纪录也删除掉)

 

foreign key(外键):建立表之间的关系

1. 建表

# 先建被关联的表,并且保证保证被关联的字段唯一
create table dept(
id int primary key,
name char(16),
comment char(50));

# 再建关联表
create table emp(
id int primary key,
name char(10),
sex enum("male","female"),
dept_id int,
foreign key(dept_id) references dept(id));   # dept_id是外键,关联到dept表的id字段

2. 插入数据

# 先往被关联表中插入纪录
insert dept values
(1,"IT","干技术的"),
(2,"Sales","卖东西的"),
(3,"Finance","花钱的");

# 再往关联表中插入数据
insert emp values
(1,"neo","male",1),
(2,"alex","female",2),
(3,"egon","male",3);   # 因为只有被关联表的关联字段建起来后关联表才能去关联;后有纪录的那张表加foreign key

上述建表方式由于没有指定 on delete cascade on update cascade,所以不能直接操作被关联表

 

如果想删除、更新同步(即 删除、更细被关联表的关联字段,关联表也自动跟着删除、更新),关联表建表时要加上 on delete cascase on update cascade   例如:foreign key(dept_id) references dept(id) on delete cascade on update cascade

# 建被关联的表
create table dept(
id int primary key,
name char(16),
comment char(50));

# 建关联表
create table emp(
id int primary key,
name char(10),
sex enum("male","female"),
dept_id int,
foreign key(dept_id) references dept(id) on delete cascade on update cascade
);     # 加上 on delete cascade on update cascade
delete from dept where id=1;
update dept set id=202 where id=2;

tips:实际项目中尽量不要把两张表建立硬性限制(foreign key),最好能从逻辑上去实现两张表的关系,即从应用程序代码的层面上去实现两张表的关系,不要再数据库利用foreign key去建立硬性关系(这样不利于扩展)

 

表与表之间的关系: 多对一、多对多、一对一

多对一:例如上面的例子,员工表emp中多个人纪录可以对应部门表dept中的一个部门纪录,但多个部门纪录却不能对应一个人(即 多个人可以在一个部门下,但一个人却不能在多个部门),这就是多对一

多对多:A表中的多条纪录可以对应B表中的一条纪录,同时B表中的多条纪录也可以对应A表中的一条纪录,这就是多对多;多对多需要专门另外建一张表来存多对多之间的关系;例如下面的书与作者的例子:

create table author(
id int primary key auto_increment,
name char(16));

create table book(
id int primary key auto_increment,
name char(50));

# 专门建一张表来保存多对多那两张表之间的关系
create table author2book(
id int not null unique auto_increment,
author_id int not null,
foreign key(author_id) references author(id)
on delete cascade
on update cascade,
book_id int not null,
foreign key(book_id) references book(id)
on delete cascade
on update cascade,
primary key(author_id,book_id));   # author_id去多对一author表中的id字段,book_id去多对一book表中的id字段

insert author(name) values("neo"),("egon"),("alex"),("wusir");
insert book(name) values("python自动化"),("linux运维"),("python全栈");

# 插入多对多之间的关系
insert author2book(author_id,book_id) values
(1,1),(1,2),(1,3),
(2,1),(2,2),
(3,2),
(4,2),(4,3);

一对一:两张表中的纪录最多只能互相对应中的一条纪录,即一一对应,例如博客园中一个昵称只能对应一个博客链接,一个博客链接也只能对应一个昵称

以培训机构的custome和student为例,客户(customer)表中的一条纪录最多只能对应student表中的一个纪录,student表中的一条纪录也一定对应customer表中的一条纪录:

# 先有潜在客户customer才能有学生(student),后有纪录的那钟表加foreign key
create table customer(
id int primary key auto_increment,
name char(10) not null,
phone int not null);

create table student(
id int primary key auto_increment,
class_name char(16) not null,
customer_id int unique,
foreign key(customer_id) references customer(id)
on delete cascade
on update cascade);   # 要想称为一对一的表,student的字段 customer_id必须要指定为 unique; 外键一定要保证 unique !!!

insert into customer(name,phone) values
('李飞机',13811341220),
('王大炮',15213146809),
('守榴弹',1867141331),
('吴坦克',1851143312),
('赢火箭',1861243314),
('战地雷',18811431230);

insert student(class_name,customer_id) values
("python周末5期",3),
("linux运维6期",5);

 

转载于:https://www.cnblogs.com/neozheng/p/8719471.html

数据库操作语句大全(sql) 一、基础 1、说明:创建数据库 CREATE DATABASE database-name 2、说明:删除数据库 drop database dbname 3、说明:备份sql server --- 创建 备份数据的 device USE master EXEC sp_addumpdevice 'disk', 'testBack', 'c:\mssql7backup\MyNwind_1.dat' --- 开始 备份 BACKUP DATABASE pubs TO testBack 4、说明:创建 create table tabname(col1 type1 [not null] [primary key],col2 type2 [not null],..) 根据已有的创建: A:create table tab_new like tab_old (使用旧创建) B:create table tab_new as select col1,col2… from tab_old definition only 5、说明:删除新 drop table tabname 6、说明:增加一个列 Alter table tabname add column col type 注:列增加后将不能删除。DB2中列加上后数据类型也不能改变,唯一能改变的是增加varchar类型的长度。 7、说明:添加主键: Alter table tabname add primary key(col) 说明:删除主键: Alter table tabname drop primary key(col) 8、说明:创建索引:create [unique] index idxname on tabname(col….) 删除索引:drop index idxname 注:索引是不可更改的,想更改必须删除重新建。 9、说明:创建视图:create view viewname as select statement 删除视图:drop view viewname 10、说明:几个简单的基本的sql语句 选择:select * from table1 where 范围 插入:insert into table1(field1,field2) values(value1,value2) 删除:delete from table1 where 范围 更新:update table1 set field1=value1 where 范围 查找:select * from table1 where field1 like ’%value1%’ ---like的语法很精妙,查资料! 排序:select * from table1 order by field1,field2 [desc] 总数:select count as totalcount from table1 求和:select sum(field1) as sumvalue from table1 平均:select avg(field1) as avgvalue from table1 最大:select max(field1) as maxvalue from table1 最小:select min(field1) as minvalue from table1 11、说明:几个高级查询运算词 A: UNION 运算符 UNION 运算符通过组合其他两个结果(例如 TABLE1 和 TABLE2)并消去中任何重复行而派生出一个结果。当 ALL 随 UNION 一起使用时(即 UNION ALL),不消除重复行。两种情况下,派生的每一行不是来自 TABLE1 就是来自 TABLE2。 B: EXCEPT 运算符 EXCEPT 运算符通过包括所有在 TABLE1 中但不在 TABLE2 中的行并消除所有重复行而派生出一个结果。当 ALL 随 EXCEPT 一起使用时 (EXCEPT ALL),不消除重复行。 C: INTERSECT 运算符 INTERSECT 运算符通过只包括 TABLE1 和 TABLE2 中都有的行并消除所有重复行而派生出一个结果。当 ALL 随 INTERSECT 一起使用时 (INTERSECT ALL),不消除重复行。 注:使用运算词的几个查询结果行必须是一致的。 12、说明:使用外连接 A、left (outer) join: 左外连接(左连接):结果集几包括连接的匹配行,也包括左连接的所有行。 SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c B:right (outer) join: 右外连接(右连接):结果集既包括连接的匹配连接行,也包括右连接的所有行。 C:full/cross (outer) join: 全外连接:不仅包括符号连接的匹配行,还包括两个连接中的所有记录。 12、分组:Group by: 一张,一旦分组 完成后,查询后只能得到组相关的信息。 组相关的信息:(统计信息) count,sum,max,min,avg 分组的标准) 在SQLServer中分组时:不能以text,ntext,image类型的字段作为分组依据 在selecte统计函数中的字段,不能和普通的字段放在一起; 13、对数据库进行操作: 分离数据库: sp_detach_db; 附加数据库:sp_attach_db 后接明,附加需要完整的路径名 14.如何修改数据库的名称: sp_renamedb 'old_name', 'new_name' 二、提升 1、说明:复制(只复制结构,源名:a 新名:b) (Access可用) 法一:select * into b from a where 11(仅用于SQlServer) 法二:select top 0 * into b from a 2、说明:拷贝(拷贝数据,源名:a 目标名:b) (Access可用) insert into b(a, b, c) select d,e,f from b; 3、说明:跨数据库之间的拷贝(具体数据使用绝对路径) (Access可用) insert into b(a, b, c) select d,e,f from b in ‘具体数据库’ where 条件 例子:..from b in '"&Server.MapPath(".")&"\data.mdb" &"' where.. 4、说明:子查询(名1:a 名2:b) select a,b,c from a where a IN (select d from b ) 或者: select a,b,c from a where a IN (1,2,3) 5、说明:显示文章、提交人和最后回复时间 select a.title,a.username,b.adddate from table a,(select max(adddate) adddate from table where table.title=a.title) b 6、说明:外连接查询(名1:a 名2:b) select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c 7、说明:在线视图查询(名1:a ) select * from (SELECT a,b,c FROM a) T where t.a > 1; 8、说明:between的用法,between限制查询数据范围时包括了边界值,not between不包括 select * from table1 where time between time1 and time2 select a,b,c, from table1 where a not between 数值1 and 数值2 9、说明:in 的使用方法 select * from table1 where a [not] in (‘值1’,’值2’,’值4’,’值6’) 10、说明:两张关联,删除主中已经在副中没有的信息 delete from table1 where not exists ( select * from table2 where table1.field1=table2.field1 ) 11、说明:四联查问题: select * from a left inner join b on a.a=b.b right inner join c on a.a=c.c inner join d on a.a=d.d where ..... 12、说明:日程安排提前五分钟提醒 SQL: select * from 日程安排 where datediff('minute',f开始时间,getdate())>5 13、说明:一条sql 语句搞定数据库分页 select top 10 b.* from (select top 20 主键字段,排序字段 from 名 order by 排序字段 desc) a,名 b where b.主键字段 = a.主键字段 order by a.排序字段 具体实现: 关于数据库分页: declare @start int,@end int @sql nvarchar(600) set @sql=’select top’+str(@end-@start+1)+’+from T where rid not in(select top’+str(@str-1)+’Rid from T where Rid>-1)’ exec sp_executesql @sql 注意:在top后不能直接跟一个变量,所以在实际应用中只有这样的进行特殊的处理。Rid为一个标识列,如果top后还有具体的字段,这样做是非常有好处的。因为这样可以避免 top的字段如果是逻辑索引的,查询的结果后实际中的不一致(逻辑索引中的数据有可能和数据表中的不一致,而查询时如果处在索引则首先查询索引) 14、说明:前10条记录 select top 10 * form table1 where 范围 15、说明:选择在每一组b值相同的数据中对应的a最大的记录的所有信息(类似这样的用法可以用于论坛每月排行榜,每月热销产品分析,按科目成绩排名,等等.) select a,b,c from tablename ta where a=(select max(a) from tablename tb where tb.b=ta.b) 16、说明:包括所有在 TableA 中但不在 TableB和TableC 中的行并消除所有重复行而派生出一个结果 (select a from tableA ) except (select a from tableB) except (select a from tableC) 17、说明:随机取出10条数据 select top 10 * from tablename order by newid() 18、说明:随机选择记录 select newid() 19、说明:删除重复记录 1),delete from tablename where id not in (select max(id) from tablename group by col1,col2,...) 2),select distinct * into temp from tablename delete from tablename insert into tablename select * from temp 评价: 这种操作牵连大量的数据的移动,这种做法不适合大容量但数据操作 3),例如:在一个外部中导入数据,由于某些原因第一次只导入了一部分,但很难判断具体位置,这样只有在下一次全部导入,这样也就产生好多重复的字段,怎样删除重复字段 alter table tablename --添加一个自增列 add column_b int identity(1,1) delete from tablename where column_b not in( select max(column_b) from tablename group by column1,column2,...) alter table tablename drop column column_b 20、说明:列出数据库里所有的名 select name from sysobjects where type='U' // U代用户 21、说明:列出里的所有的列名 select name from syscolumns where id=object_id('TableName') 22、说明:列示type、vender、pcs字段,以type字段排列,case可以方便地实现多重选择,类似select 中的case。 select type,sum(case vender when 'A' then pcs else 0 end),sum(case vender when 'C' then pcs else 0 end),sum(case vender when 'B' then pcs else 0 end) FROM tablename group by type 显示结果: type vender pcs 电脑 A 1 电脑 A 1 光盘 B 2 光盘 A 2 手机 B 3 手机 C 3 23、说明:初始化table1 TRUNCATE TABLE table1 24、说明:选择从10到15的记录 select top 5 * from (select top 15 * from table order by id asc) table_别名 order by id desc 三、技巧 1、1=1,1=2的使用,在SQL语句组合时用的较多 “where 1=1” 是示选择全部 “where 1=2”全部不选, 如: if @strWhere !='' begin set @strSQL = 'select count(*) as Total from [' + @tblName + '] where ' + @strWhere end else begin set @strSQL = 'select count(*) as Total from [' + @tblName + ']' end 我们可以直接写成 错误!未找到目录项。 set @strSQL = 'select count(*) as Total from [' + @tblName + '] where 1=1 安定 '+ @strWhere 2、收缩数据库 --重建索引 DBCC REINDEX DBCC INDEXDEFRAG --收缩数据和日志 DBCC SHRINKDB DBCC SHRINKFILE 3、压缩数据库 dbcc shrinkdatabase(dbname) 4、转移数据库给新用户以已存在用户权限 exec sp_change_users_login 'update_one','newname','oldname' go 5、检查备份集 RESTORE VERIFYONLY from disk='E:\dvbbs.bak' 6、修复数据库 ALTER DATABASE [dvbbs] SET SINGLE_USER GO DBCC CHECKDB('dvbbs',repair_allow_data_loss) WITH TABLOCK GO ALTER DATABASE [dvbbs] SET MULTI_USER GO 7、日志清除 SET NOCOUNT ON DECLARE @LogicalFileName sysname, @MaxMinutes INT, @NewSize INT USE tablename -- 要操作数据库名 SELECT @LogicalFileName = 'tablename_log', -- 日志文件名 @MaxMinutes = 10, -- Limit on time allowed to wrap log. @NewSize = 1 -- 你想设定的日志文件的大小(M) Setup / initialize DECLARE @OriginalSize int SELECT @OriginalSize = size FROM sysfiles WHERE name = @LogicalFileName SELECT 'Original Size of ' + db_name() + ' LOG is ' + CONVERT(VARCHAR(30),@OriginalSize) + ' 8K pages or ' + CONVERT(VARCHAR(30),(@OriginalSize*8/1024)) + 'MB' FROM sysfiles WHERE name = @LogicalFileName CREATE TABLE DummyTrans (DummyColumn char (8000) not null) DECLARE @Counter INT, @StartTime DATETIME, @TruncLog VARCHAR(255) SELECT @StartTime = GETDATE(), @TruncLog = 'BACKUP LOG ' + db_name() + ' WITH TRUNCATE_ONLY' DBCC SHRINKFILE (@LogicalFileName, @NewSize) EXEC (@TruncLog) -- Wrap the log if necessary. WHILE @MaxMinutes > DATEDIFF (mi, @StartTime, GETDATE()) -- time has not expired AND @OriginalSize = (SELECT size FROM sysfiles WHERE name = @LogicalFileName) AND (@OriginalSize * 8 /1024) > @NewSize BEGIN -- Outer loop. SELECT @Counter = 0 WHILE ((@Counter < @OriginalSize / 16) AND (@Counter < 50000)) BEGIN -- update INSERT DummyTrans VALUES ('Fill Log') DELETE DummyTrans SELECT @Counter = @Counter + 1 END EXEC (@TruncLog) END SELECT 'Final Size of ' + db_name() + ' LOG is ' + CONVERT(VARCHAR(30),size) + ' 8K pages or ' + CONVERT(VARCHAR(30),(size*8/1024)) + 'MB' FROM sysfiles WHERE name = @LogicalFileName DROP TABLE DummyTrans SET NOCOUNT OFF 8、说明:更改某个 exec sp_changeobjectowner 'tablename','dbo' 9、存储更改全部 CREATE PROCEDURE dbo.User_ChangeObjectOwnerBatch @OldOwner as NVARCHAR(128), @NewOwner as NVARCHAR(128) AS DECLARE @Name as NVARCHAR(128) DECLARE @Owner as NVARCHAR(128) DECLARE @OwnerName as NVARCHAR(128) DECLARE curObject CURSOR FOR select 'Name' = name, 'Owner' = user_name(uid) from sysobjects where user_name(uid)=@OldOwner order by name OPEN curObject FETCH NEXT FROM curObject INTO @Name, @Owner WHILE(@@FETCH_STATUS=0) BEGIN if @Owner=@OldOwner begin set @OwnerName = @OldOwner + '.' + rtrim(@Name) exec sp_changeobjectowner @OwnerName, @NewOwner end -- select @name,@NewOwner,@OldOwner FETCH NEXT FROM curObject INTO @Name, @Owner END close curObject deallocate curObject GO 10、SQL SERVER中直接循环写入数据 declare @i int set @i=1 while @i<30 begin insert into test (userid) values(@i) set @i=@i+1 end 案例: 有如下,要求就裱中所有沒有及格的成績,在每次增長0.1的基礎上,使他們剛好及格: Name score Zhangshan 80 Lishi 59 Wangwu 50 Songquan 69 while((select min(score) from tb_table)<60) begin update tb_table set score =score*1.01 where score60 break else continue end 数据开发-经典 1.按姓氏笔画排序: Select * From TableName Order By CustomerName Collate Chinese_PRC_Stroke_ci_as //从少到多 2.数据库加密: select encrypt('原始密码') select pwdencrypt('原始密码') select pwdcompare('原始密码','加密后密码') = 1--相同;否则不相同 encrypt('原始密码') select pwdencrypt('原始密码') select pwdcompare('原始密码','加密后密码') = 1--相同;否则不相同 3.取回中字段: declare @list varchar(1000), @sql nvarchar(1000) select @list=@list+','+b.name from sysobjects a,syscolumns b where a.id=b.id and a.name='A' set @sql='select '+right(@list,len(@list)-1)+' from A' exec (@sql) 4.查看硬盘分区: EXEC master..xp_fixeddrives 5.比较A,B是否相等: if (select checksum_agg(binary_checksum(*)) from A) = (select checksum_agg(binary_checksum(*)) from B) print '相等' else print '不相等' 6.杀掉所有的事件探察器进程: DECLARE hcforeach CURSOR GLOBAL FOR SELECT 'kill '+RTRIM(spid) FROM master.dbo.sysprocesses WHERE program_name IN('SQL profiler',N'SQL 事件探查器') EXEC sp_msforeach_worker '?' 7.记录搜索: 开头到N条记录 Select Top N * From ------------------------------- N到M条记录(要有主索引ID) Select Top M-N * From Where ID in (Select Top M ID From ) Order by ID Desc ---------------------------------- N到结尾记录 Select Top N * From Order by ID Desc 案例 例如1:一张有一万多条记录,的第一个字段 RecID 是自增长字段, 写一个SQL语句, 找出的第31到第40个记录。 select top 10 recid from A where recid not in(select top 30 recid from A) 分析:如果这样写会产生某些问题,如果recid在中存在逻辑索引。 select top 10 recid from A where……是从索引中查找,而后面的select top 30 recid from A则在数据表中查找,这样由于索引中的顺序有可能和数据表中的不一致,这样就导致查询到的不是本来的欲得到的数据。 解决方案 1, 用order by select top 30 recid from A order by ricid 如果该字段不是自增长,就会出现问题 2, 在那个子查询中也加条件:select top 30 recid from A where recid>-1 例2:查询中的最后以条记录,并不知道这个共有多少数据,以及结构。 set @s = 'select top 1 * from T where pid not in (select top ' + str(@count-1) + ' pid from T)' print @s exec sp_executesql @s 9:获取当前数据库中的所有用户 select Name from sysobjects where xtype='u' and status>=0 10:获取某一个的所有字段 select name from syscolumns where id=object_id('名') select name from syscolumns where id in (select id from sysobjects where type = 'u' and name = '名') 两种方式的效果相同 11:查看与某一个相关的视图、存储过程、函数 select a.* from sysobjects a, syscomments b where a.id = b.id and b.text like '%名%' 12:查看当前数据库中所有存储过程 select name as 存储过程名称 from sysobjects where xtype='P' 13:查询用户创建的所有数据库 select * from master..sysdatabases D where sid not in(select sid from master..syslogins where name='sa') 或者 select dbid, name AS DB_NAME from master..sysdatabases where sid 0x01 14:查询某一个的字段和数据类型 select column_name,data_type from information_schema.columns where table_name = '名' 15:不同服务器数据库之间的数据操作 --创建链接服务器 exec sp_addlinkedserver 'ITSV ', ' ', 'SQLOLEDB ', '远程服务器名或ip地址 ' exec sp_addlinkedsrvlogin 'ITSV ', 'false ',null, '用户名 ', '密码 ' --查询示例 select * from ITSV.数据库名.dbo.名 --导入示例 select * into from ITSV.数据库名.dbo.名 --以后不再使用时删除链接服务器 exec sp_dropserver 'ITSV ', 'droplogins ' --连接远程/局域网数据(openrowset/openquery/opendatasource) --1、openrowset --查询示例 select * from openrowset( 'SQLOLEDB ', 'sql服务器名 '; '用户名 '; '密码 ',数据库名.dbo.名) --生成本地 select * into from openrowset( 'SQLOLEDB ', 'sql服务器名 '; '用户名 '; '密码 ',数据库名.dbo.名) --把本地导入远程 insert openrowset( 'SQLOLEDB ', 'sql服务器名 '; '用户名 '; '密码 ',数据库名.dbo.名) select *from 本地 --更新本地 update b set b.列A=a.列A from openrowset( 'SQLOLEDB ', 'sql服务器名 '; '用户名 '; '密码 ',数据库名.dbo.名)as a inner join 本地 b on a.column1=b.column1 --openquery用法需要创建一个连接 --首先创建一个连接创建链接服务器 exec sp_addlinkedserver 'ITSV ', ' ', 'SQLOLEDB ', '远程服务器名或ip地址 ' --查询 select * FROM openquery(ITSV, 'SELECT * FROM 数据库.dbo.名 ') --把本地导入远程 insert openquery(ITSV, 'SELECT * FROM 数据库.dbo.名 ') select * from 本地 --更新本地 update b set b.列B=a.列B FROM openquery(ITSV, 'SELECT * FROM 数据库.dbo.名 ') as a inner join 本地 b on a.列A=b.列A --3、opendatasource/openrowset SELECT * FROM opendatasource( 'SQLOLEDB ', 'Data Source=ip/ServerName;User ID=登陆名;Password=密码 ' ).test.dbo.roy_ta --把本地导入远程 insert opendatasource( 'SQLOLEDB ', 'Data Source=ip/ServerName;User ID=登陆名;Password=密码 ').数据库.dbo.名 select * from 本地 SQL Server基本函数 SQL Server基本函数 1.字符串函数 长度与分析用 1,datalength(Char_expr) 返回字符串包含字符数,但不包含后面的空格 2,substring(expression,start,length) 取子串,字符串的下标是从“1”,start为起始位置,length为字符串长度,实际应用中以len(expression)取得其长度 3,right(char_expr,int_expr) 返回字符串右边第int_expr个字符,还用left于之相反 4,isnull( check_expression , replacement_value )如果check_expression為空,則返回replacement_value的值,不為空,就返回check_expression字符操作类 5,Sp_addtype 自定義數據類型 例如:EXEC sp_addtype birthday, datetime, 'NULL' 6,set nocount {on|off} 使返回的结果中不包含有关受 Transact-SQL 语句影响的行数的信息。如果存储过程中包含的一些语句并不返回许多实际的数据,则该设置由于大量减少了网络流量,因此可显著提高性能。SET NOCOUNT 设置是在执行或运行时设置,而不是在分析时设置。 SET NOCOUNT 为 ON 时,不返回计数(示受 Transact-SQL 语句影响的行数)。 SET NOCOUNT 为 OFF 时,返回计数 常识 在SQL查询中:from后最多可以跟多少张或视图:256 在SQL语句中出现 Order by,查询时,先排序,后取 在SQL中,一个字段的最大容量是8000,而对于nvarchar(4000),由于nvarchar是Unicode码。 SQLServer2000同步复制技术实现步骤 一、 预备工作 1.发布服务器,订阅服务器都创建一个同名的windows用户,并设置相同的密码,做为发布快照文件夹的有效访问用户 --管理工具 --计算机管理 --用户和组 --右键用户 --新建用户 --建立一个隶属于administrator组的登陆windows的用户(SynUser) 2.在发布服务器上,新建一个共享目录,做为发布的快照文件的存放目录,操作: 我的电脑--D:\ 新建一个目录,名为: PUB --右键这个新建的目录 --属性--共享 --选择"共享该文件夹" --通过"权限"按纽来设置具体的用户权限,保证第一步中创建的用户(SynUser) 具有对该文件夹的所有权限 --确定 3.设置SQL代理(SQLSERVERAGENT)服务的启动用户(发布/订阅服务器均做此设置) 开始--程序--管理工具--服务 --右键SQLSERVERAGENT --属性--登陆--选择"此账户" --输入或者选择第一步中创建的windows登录用户名(SynUser) --"密码"中输入该用户的密码 4.设置SQL Server身份验证模式,解决连接时的权限问题(发布/订阅服务器均做此设置) 企业管理器 --右键SQL实例--属性 --安全性--身份验证 --选择"SQL Server 和 Windows" --确定 5.在发布服务器和订阅服务器上互相注册 企业管理器 --右键SQL Server组 --新建SQL Server注册... --下一步--可用的服务器中,输入你要注册的远程服务器名 --添加 --下一步--连接使用,选择第二个"SQL Server身份验证" --下一步--输入用户名和密码(SynUser) --下一步--选择SQL Server组,也可以创建一个新组 --下一步--完成 6.对于只能用IP,不能用计算机名的,为其注册服务器别名(此步在实施中没用到) (在连接端配置,比如,在订阅服务器上配置的话,服务器名称中输入的是发布服务器的IP) 开始--程序--Microsoft SQL Server--客户端网络实用工具 --别名--添加 --网络选择"tcp/ip"--服务器别名输入SQL服务器名 --连接参数--服务器名称中输入SQL服务器ip地址 --如果你修改了SQL的端口,取消选择"动态决定端口",并输入对应的端口号 二、 正式配置 1、配置发布服务器 打开企业管理器,在发布服务器(B、C、D)上执行以下步骤: (1) 从[工具]下拉菜单的[复制]子菜单中选择[配置发布、订阅服务器和分发]出现配置发布和分发向导 (2) [下一步] 选择分发服务器 可以选择把发布服务器自己作为分发服务器或者其他sql的服务器(选择自己) (3) [下一步] 设置快照文件夹 采用默认\\servername\Pub (4) [下一步] 自定义配置 可以选择:是,让我设置分发数据库属性启用发布服务器或设置发布设置 否,使用下列默认设置(推荐) (5) [下一步] 设置分发数据库名称和位置 采用默认值 (6) [下一步] 启用发布服务器 选择作为发布的服务器 (7) [下一步] 选择需要发布的数据库和发布类型 (8) [下一步] 选择注册订阅服务器 (9) [下一步] 完成配置 2、创建出版物 发布服务器B、C、D上 (1)从[工具]菜单的[复制]子菜单中选择[创建和管理发布]命令 (2)选择要创建出版物的数据库,然后单击[创建发布] (3)在[创建发布向导]的提示对话框中单击[下一步]系统就会弹出一个对话框。对话框上的内容是复制的三个类型。我们现在选第一个也就是默认的快照发布(其他两个大家可以去看看帮助) (4)单击[下一步]系统要求指定可以订阅该发布的数据库服务器类型, SQLSERVER允许在不同的数据库如 orACLE或ACCESS之间进行数据复制。 但是在这里我们选择运行"SQL SERVER 2000"的数据库服务器 (5)单击[下一步]系统就弹出一个定义文章的对话框也就是选择要出版的 注意: 如果前面选择了事务发布 则再这一步中只能选择带有主键的 (6)选择发布名称和描述 (7)自定义发布属性 向导提供的选择: 是 我将自定义数据筛选,启用匿名订阅和或其他自定义属性 否 根据指定方式创建发布 (建议采用自定义的方式) (8)[下一步] 选择筛选发布的方式 (9)[下一步] 可以选择是否允许匿名订阅 1)如果选择署名订阅,则需要在发布服务器上添加订阅服务器 方法: [工具]->[复制]->[配置发布、订阅服务器和分发的属性]->[订阅服务器] 中添加 否则在订阅服务器上请求订阅时会出现的提示:改发布不允许匿名订阅 如果仍然需要匿名订阅则用以下解决办法 [企业管理器]->[复制]->[发布内容]->[属性]->[订阅选项] 选择允许匿名请求订阅 2)如果选择匿名订阅,则配置订阅服务器时不会出现以上提示 (10)[下一步] 设置快照 代理程序调度 (11)[下一步] 完成配置 当完成出版物的创建创建出版物的数据库也就变成了一个共享数据库 有数据 srv1.名..author有字段:id,name,phone, srv2.名..author有字段:id,name,telphone,adress 要求: srv1.名..author增加记录则srv1.名..author记录增加 srv1.名..author的phone字段更新,则srv1.名..author对应字段telphone更新 --*/ --大致的处理步骤 --1.在 srv1 上创建连接服务器,以便在 srv1 中操作 srv2,实现同步 exec sp_addlinkedserver 'srv2','','SQLOLEDB','srv2的sql实例名或ip' exec sp_addlinkedsrvlogin 'srv2','false',null,'用户名','密码' go --2.在 srv1 和 srv2 这两台电脑中,启动 msdtc(分布式事务处理服务),并且设置为自动启动 。我的电脑--控制面板--管理工具--服务--右键 Distributed Transaction Coordinator--属性--启动--并将启动类型设置为自动启动 go --然后创建一个作业定时调用上面的同步处理存储过程就行了 企业管理器 --管理 --SQL Server代理 --右键作业 --新建作业 --"常规"项中输入作业名称 --"步骤"项 --新建 --"步骤名"中输入步骤名 --"类型"中选择"Transact-SQL 脚本(TSQL)" --"数据库"选择执行命令的数据库 --"命令"中输入要执行的语句: exec p_process --确定 --"调度"项 --新建调度 --"名称"中输入调度名称 --"调度类型"中选择你的作业执行安排 --如果选择"反复出现" --点"更改"来设置你的时间安排 然后将SQL Agent服务启动,并设置为自动启动,否则你的作业不会被执行 设置方法: 我的电脑--控制面板--管理工具--服务--右键 SQLSERVERAGENT--属性--启动类型--选择"自动启动"--确定. --3.实现同步处理的方法2,定时同步 --在srv1中创建如下的同步处理存储过程 create proc p_process as --更新修改过的数据 update b set name=i.name,telphone=i.telphone from srv2.名.dbo.author b,author i where b.id=i.id and (b.name i.name or b.telphone i.telphone) --插入新增的数据 insert srv2.名.dbo.author(id,name,telphone) select id,name,telphone from author i where not exists( select * from srv2.名.dbo.author where id=i.id) --删除已经删除的数据(如果需要的话) delete b from srv2.名.dbo.author b where not exists( select * from author where id=b.id) go
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值