面试引发的两个问题
文本(字符串)在数据库中的存储可以有那几种数据类型,各类型的区别是什么?数据据库的两个关系表有那几种连接方式?每种方式的区别是什么?,前几日一个面试者来到公司面试,他说数据库比较熟,老大直接抛出了这几个问题。我想这问题也太基础了吧,对于一个熟悉数据库的来说简直小菜一碟,然而结果确出乎我的想像,前一个问题他答错了,后一个问题答的不全。
现在我们一起来看一下这两个问题,希望那些概念不清的同学友,抓紧时间打牢基础了,不要在面试的时候,连基本的都答不上来,那就不好玩了。
第一个问题:文本(字符串)在数据库中的存储可以有那几种数据类型?各类型的区别是什么?
1、 varchar: 可变长度的非 Unicode 数据,最长为 8,000 个字符。
2、nvarchar:可变长度 Unicode 数据,其最大长度为 4,000 字符。
3、char: 固定长度的非 Unicode 字符数据,最大长度为 8,000 个字符。
4、nchar:固定长度的 Unicode 数据,最大长度为 4,000 个字符。
定长或变长
所谓定长就是长度固定的,当输入的数据长度没有达到指定的长度时将自动以英文空格在其后面填充,使长度达到相应的长度;有var前缀的,表示是实际存储空间是变长的,比如varchar,nvarchar变长字符数据则不会以空格填充,比较例外的是,text存储的也是可变长。
Unicode或非Unicode
数据库中,英文字符只需要一个字节存储就足够了,但汉字和其他众多非英文字符,则需要两个字节存储。如果英文与汉字同时存在,由于占用空间数不同,容易造成混乱,导致读取出来的字符串是乱码。Unicode字符集就是为了解决字符集这种不兼容的问题而产生的,它所有的字符都用两个节表示,即英文字符也是用两个字节表示。而前缀n就表示Unicode字符,比如nchar,nvarchar,这两种类型使用了Unicode字符集。
char、varchar、nchar、nvarchar特点比较
CHAR
CHAR存储定长数据很方便,CHAR字段上的索引效率级高,比如定义char(10),那么不论你存储的数据是否达到了10个字节,都要占去10个字节的空间。
VARCHAR
存储变长数据,但存储效率没有CHAR高,如果一个字段可能的值是不固定长度的,我们只知道它不可能超过10个字符,把它定义为 VARCHAR(10)是最合算的。VARCHAR类型的实际长度是它的值的实际长度+1。为什么"+1"呢?这一个字节用于保存实际使用了多大的长度。
从空间上考虑,用varchar合适;从效率上考虑,用char合适,关键是根据实际情况找到权衡点。
TEXT
text存储可变长度的非Unicode数据,最大长度为2^31-1(2,147,483,647)个字符。
NCHAR、NVARCHAR、NTEXT
这三种从名字上看比前面三种多了个"N"。和char、varchar比较起来,nchar、nvarchar最多存储4000个字符,不论是英文还是汉字;而char、varchar最多能存储8000个英文,4000个汉字。可以看出使用nchar、nvarchar数据类型时不用担心输入的字符是英文还是汉字,较为方便,但在存储英文时数量上有些损失。
所以一般来说,如果含有中文字符,用nchar/nvarchar,如果纯英文和数字,用char/varchar
使用选择上
在使用上没有一个明确的规范,可根据个人情况和使用的环境而定,
如果数据量非常大,又能100%确定长度且保存只是ansi字符,那么char
能确定长度又不一定是ansi字符,那么用nchar,如性别
对于超大数据,如文章内容,使用nText
其他的通用nvarchar
第二个问题:数据据库的两个关系表有那几种连接方式?每种方式的区别是什么?
关系数据库中关系表间的连接主要有:内连接和外连接。
内连接:把两个表中数据对应的数据查询出来。
外连接:以某个表为基础把对应数据查询出来(全连接是以多个表为基础),其中又包括左连接和右连接两种。
比如,有下面两个关系表student和grade。
Student表
No |
Name |
1 |
A |
2 |
B |
3 |
C |
4 |
D |
Grade表
No |
Grade |
1 |
90 |
2 |
98 |
3 |
95 |
5 |
100 |
内连接inner join(在两个表中查询满足条件的对应数据)。
语法:SELECT * FROM student INNER JOIN grade ON student.no=grade.no
结果:
student.no |
student.name |
grade.no |
grade.grade |
1 |
A |
1 |
90 |
2 |
B |
2 |
98 |
3 |
C |
3 |
95 |
左连接:包含左表中所有数据,右表中满足条件的对应数据。
语法:SELECT * FROM student LEFT JOIN grade ON student.no=grade.no
结果:
student.no |
student.name |
grade.no |
grade.grade |
1 |
A |
1 |
90 |
2 |
B |
2 |
98 |
3 |
C |
3 |
95 |
4 |
D |
NULL |
NULL |
右连接:包含右表中所有数据,左表中满足条件的对应数据。
语法:SELECT * FROM student RIGHT JOIN grade ON student.no=grade.no
结果:
student.no |
student.name |
grade.no |
grade.grade |
1 |
A |
1 |
90 |
2 |
B |
2 |
98 |
3 |
C |
3 |
95 |
NULL |
NULL |
5 |
100 |
全连接:左右表中所有数据全部查询出来。
语法:SELECT * FROM student FULL JOIN grade ON student.no=grade.no
结果:
student.no |
student.name |
grade.grade |
1 |
A |
90 |
2 |
B |
98 |
3 |
C |
95 |
4 |
D |
NULL |
1 |
A |
90 |
2 |
B |
98 |
3 |
C |
95 |
5 |
NULL |
100 |
以上部分内容来自于网上网友的博文,请原谅我的厚颜,搬到了自己的文章中,最后想说的是,大家 一定要把基础打好。面试的时候不要慌,不会的和自己感到模糊的不要写在简历上,也不要随意说,不会的就说不会,不然不懂装懂就不好了。也就不好继续和你的面试官谈下去了。