键盘敲烂,月薪过万作业不做,等于没学
当前系列: SQL 修改讲义
既然我们在工作台(VS/workbench中使用GUI(图形界面)就能进行完成建库建表增删改查等一系列操作,我们为什么还需要学习SQL语句呢?
  1. 应用程序通过代码操作数据库的时候,只能使用SQL语句。实际上我们在GUI上所做的所有操作,都会被转化成SQL语句,再发送给数据库执行:数据库本身只认SQL。
  2. 后面ORM工具会生成建库建表的脚本(SQL语句),我们要能看得懂,以便调试/部署等


数据库

创建

CREATE DATABASE YqBang;
逐字翻译:创建 数据库 YqBang,非常容易理解。观察这条SQL语句,它主要由以下这些内容组成:
  1. 关键字。如:CREATE、DATABASE,在query窗口中,这些关键字都被Visual Studio进行了高亮(加蓝色或灰色)。他们是千万不能拼写错误的,一旦拼写错误就不会有高亮,提示你进行拼写检查(同时有可能出现波浪线)
  2. 用户自定义(即由你自己确定)的名称,如:Yqbang。注意虽然这些名称由你定义,但你必须遵守一定的命名规则规范。
  3. 符号:注意这些(以及所有编程语言)符号都是半角的(使用英文输入法)!不是(),而是();不是,而是,,不是;而是;……这是初学者最容易犯的错误之一,^_^
  4. 空格:用于区分单词。多个空格会被视为一个空格。
  5. 换行:在SQL中,换行等同于空格。换行和空格只是为了提高代码的可读性(更容易让开发者阅读理解),不影响代码的执行。

另外:

  • SQL不区分大小写
  • 自动忽略换行
  • 注释:使用两个短横线(--),--之后的整行内容都不会被执行,通常用于描述说明


T-SQL
mysql
保留字/关键字/非规范符号等做库名、表名、列名等 方括号括住,如:[17bang]
反引号括住,如`17bang`
分号;用于一条SQL语句的末尾,标志一条SQL语句的结束。
可以(但不建议)省略
命令行窗口,或某些控制台必须加

切换

USE YqBang; -- 切换到数据库17bang

删除

SQL语句:

DROP DATABASE YqBang;
但是,使用时注意两个问题:
  1. 不能删除正在使用中的数据库(比如当前数据库):所以要使用USE 切换到其他数据库,如果没有其他自定义数据库,可以切换到系统数据库
    • SQL Server的master,或者
    • mysql的sys
  2. 不能删除不存在的数据库:删除就会报错。不想报错的话,用 IF EXISTS 来判断数据库是否存在,如下所示:
    -- 如果数据库YqBang存在就删除它,否则就啥也不做
    DROP DATABASE IF EXISTS YqBang


创建

其实在建表视图底部就可以观察到自动生成的建表T-SQL语句:



dbo是database owner(数据库所有者)的首字母缩写,可以理解为数据库的一个特殊用户(或默认用户),一般可以省略。

延伸阅读:一个数据库可以由多个用户访问,多个用户都可以创建“同名”的表,可以在这些表前面加上用户名加以区分。

比如Jimmy.Student,和ATai.Student,这是用户Jimmy和ATai各自不同的表。

dbo.Table即用户dbo的表Table,但dbo比较特殊——sysadmin下的所有用户都自动映射到dbo……

`17bang`指的是数据库

上述内容构成了一段完整的SQL语句。我们逐行解释:
-- 创建 表格 [dbo].[Table],[Table]指表名,由开发人员指定。 
CREATE TABLE [dbo].[Table] 
( -- 括起来的部分确定表格的结构,包括了: 
	-- Id列,只能是INT类型,不能为NULL值,是主键(后文详解) 
	[Id] INT NOT NULL PRIMARY KEY,
	-- UserName列,只能是NCHAR(10)类型,可以为NULL [Name] NVARCHAR(10) NULL  
);

数据类型

SQL是“强类型”的,设计表头的时候就应该指定数据类型。

相比其他语言,数据库的数据类型设置更加具体复杂,因为这样可以更高效的存储

把数据想象成大小不一的砖头(块,block),放在不同类型的盒子(box)里:盒子太小砖头装不进去,盒子太大浪费空间。

更好的规划盒子,让砖头放进去可以刚刚好或者空余少,就能够节约存储空间:

SQL为我们提供了很多数据类型,但常用的数据类型有:

文本类型

表示数据以文本(字符串)形式存储,比如:“大飞哥”、“17bang”、“源栈”。

文本类型的数据一般需要指定其长度(Length),即该文本需要占用的字节数(不是字符个数)。

长度在类型后面用圆括号括起来,默认为1,最大值为8000。又可以分为:

  • 定长文本比如:CHAR(10)。如果你录入的数据长度不足10个,数据库会使用空白自动给你补足。
  • 变长文本:如果存储的数据长度是可变的,就在CHAR前面加一个VAR,比如VARCHAR(10),就意味着可以存储最长长度为10的文本数据。

如果最大长度可能超过8000,就只能使用TEXT,通常用于大篇幅不限字数的文章正文等。另:

  • mysql中文本编码在建库建表时指定,然后就可以直接存储汉字等特殊符号;
  • T-SQL中要存储汉字等特殊符号,需要在类型前面加N(比如NCHAR/NVARCHAR/NTEXT),以后用SQL插入数据时一样要在字符串前加N(比如:N'大飞哥'、N'源栈')。

数值类型

表示存储的数据是数值,比如:整数986、小数3.14、负数-19.8。又可以细分为:

整数

最常用的是INT,其他还有tinyint,smallint和bigint

他们的区别是能够容纳的数据大小不一样,比如tinyint就只能存储0-255的数据,超过这个大小的数据(比如986)就无法存放进去。

那为什么不通通使用最大的bigint呢?因为要节省存储空间。能够容纳更大数据的类型,所需要的空间更大。

合理的选择数据类型,比如存储一个人的年龄,就使用tinyint好了,没有人的年龄会小于0大于255,这比使用int要节省1/4的磁盘空间(tinyint的存储空间是1Byte,int是4Bytes)。

小数

常用的又有两种:

  1. decimal和numeric:可以精确地指定小数的整体长度和位数。比如decimal(5,2),意思是数据总共最多可以有5位数字,同时小数点后面必须有2位(不足两位自动用0补足),所以:
    a)合法的,可以是:1.7、12.35和326.89
    b)非法的,包括:1986(会自动补足成1986.00,数字个数超过5)、19.8666(会自动四舍五入成19.87)
    参考:decimal and numeric
  2. float和real:小数位数可变的(非精确的)存储方式。比如你输入32,整数,SQL Server就存放为32,不会像decimal那样加小数点并补0为32.00;你也可以输入32.986,SQL Server就把它存储为32.986。 参考:float and real

真假类型

表示只能存储“真(是)”和“假(否)”两种值,

  • SQL Server里bit
  • mysql里用tinyint(1)

本质上还是一个整数类型:用1表示真,0表示假

时间类型

表示存储的是时间,常用的有:

  • date:日期,比如'2019/10/4'(SQL中需要加单引号),表示2019年10月4日
  • time:时间,比如'16:42 31',表示16点42分31秒
  • datetime:上面的日期加时间

修改

所有修改表结构的语句,都首先要使用ALTER TABLE,比如:

ALTER TABLE Student

上述SQL语句指明:修改 表 Student。接下来可以进行列的增删改。

比如增加列 Score,该列的数据类型为DECIMAL(3,1),那就需要在 ALTER TABLE Student 之后添加:

ALTER TABLE Student ADD Score DECIMAL(3,1);
删除列 Score,同样在ALTER TABLE Student 之后添加(后文不再特别指明):
ALTER TABLE Student DROP COLUMN Score;

还可以修改列

T-SQL mysql
ALTER TABLE Student
ALTER COLUMN SCORE FLOAT NULL;
ALTER TABLE Student
modify COLUMN SCORE FLOAT NULL;
修改表名/列名需要使用系统存储过程
ALTER TABLE Student
change `Name` SName VARCHAR(50);

注意:为了保证数据安全,不能在两种完全不兼容(incompatible)的数据类型之间进行修改,比如INT转换成BIGINT,是完成没有问题的,986从INT转换成BIGINT还是986;但INT无法转换成DATETIME,986怎么转换成一个时间呢?

删除

DROP TABLE Student;


批处理(仅:SQL Server)

同时运行建库和切换数据库的代码试试:

CREATE DATABASE YqBang; 
USE YqBang;

你会得到一个错误提示,说数据库不存在:

Msg 911, Level 16, State 1, Line 2 Database '17bang' does not exist. Make sure that the name is entered correctly.17bang

这个数据库我不是刚建立了的么?

OK,要理解这一点,需要我们首先理解一个 批处理 的概念

简单的说,SQL Server会把所有发送给它的SQL语句作为一个完整的可执行的单元进行处理(包括解析、优化、执行等等),这些SQL语句被称之为“一批”。

上述建库和切换数据库的命令无法在同一批次中完成,或者你可以理解成:创建一个数据库,这个数据库只能在下一“批次”才能被使用。

所以你有两个选择:

  1. 人工的分两批执行,第一次选中CREATE DATABASE YqBang,执行;执行完毕之后,再一次的选中USE YqBang,执行。
  2. 使用 GO 来分隔SQL语句。GO并不是一条SQL语句,而是一个对SQL Server的客户端(比如VS的new query窗口)有效的命令。客户端检测到 GO,就会以GO为分隔符,将SQL语句分隔成若干批发送给SQL Server,由SQL Server分批处理。所以,上述建库转库的SQL语句可以写成如下样式,然后整个一次 Ctrl+Shift+E 要求执行:
    CREATE DATABASE YqBang; 
    GO --GO后面不要加; 
    USE YqBang;


作业

使用SQL语句(以后所有作业均是要求使用SQL语句完成,不再额外声明)

  1. 新建一个数据库:17bang,能指定/查看该数据库存放位置
  2. 观察“一起帮”的:
    1. 注册功能,建表User:包含UserName(用户名),Password(密码)
    2. 发布求助功能:
      1. 建表Problem,包含:Id、Title(标题)、Content(正文)、NeedRemoteHelp(需要远程求助)、Reward(悬赏)、PublishDateTime(发布时间)……
      2. 内容发布功能:建表Keyword:包含Name(名称),Used(使用次数)
    注意为这些列选择合适的数据类型。
  3. 为User表添加一列:邀请人(InvitedBy),类型为NVARCHAR(10)
  4. 将InvitedBy类型修改为INT
  5. 删除列InvitedBy
学习笔记
源栈学历
大多数人,都低估了编程学习的难度,而高估了自己的学习能力和毅力。

作业

  1. SQL建库建表

    使用SQL语句(以后所有作业均是要求使用SQL语句完成,不再额外声明)

    1. 新建一个数据库:17bang,能指定/查看该数据库存放位置
    2. 观察“一起帮”的:
      1. 注册功能,建表User:包含UserName(用户名),Password(密码)
      2. 发布求助功能:
        1. 建表Problem,包含:Id、Title(标题)、Content(正文)、NeedRemoteHelp(需要远程求助)、Reward(悬赏)、PublishDateTime(发布时间)……
        2. 内容发布功能:建表Keyword:包含Name(名称),Used(使用次数)
      注意为这些列选择合适的数据类型。
    3. 为User表添加一列:邀请人(InvitedBy),类型为NVARCHAR(10)
    4. 将InvitedBy类型修改为INT
    5. 删除列InvitedBy
觉得很 ,不要忘记分享哟!

任何问题,都可以直接加 QQ群:273534701

在当前系列 SQL 中继续学习:

多快好省!前端后端,线上线下,名师精讲

  • 先学习,后付费;
  • 不满意,不要钱。
  • 编程培训班,我就选源栈

更多了解 加:

QQ群:273534701

答疑解惑,远程debug……

B站 源栈-小九 的直播间

写代码要保持微笑 (๑•̀ㅂ•́)و✧

公众号:源栈一起帮

二维码