is-a,has-a,like-a是什么 sql server中,N''表示什么意思? 关于SQL SERVER的N前缀的理解

https://blog.csdn.net/ooppookid/article/details/51174122#commentBox

1、is-a,has-a,like-a是什么

在面向对象设计的领域里,有若干种设计思路,主要有如下三种:
is-a、has-a、like-a

2、is-a是什么

is-a,顾名思义,是一个,代表继承关系。
如果A is-a B,那么B就是A的父类

3、has-a是什么

has-a,顾名思义,有一个,代表从属关系
如果A has a B,那么B就是A的组成部分
同一种类的对象,通过它们的属性的不同值来区别。
例如一台PC机的操作系统是Windows,另一台PC机的操作系统是Linux。操作系统是PC机的一个成员变量,根据这一成员变量的不同值,可以区分不同的PC机对象。

4、 like-a是什么

like-a,顾名思义,像一个,代表组合关系
如果A like a B,那么B就是A的接口
新类型有老类型的接口,但还包含其他函数,所以不能说它们完全相同
例如一台手机可以说是一个微型计算机,但是手机的通讯功能显然不是计算机具备的行为,所以手机继承了计算机的特性,同时需要实现通讯功能,而通讯功能需要作为单独接口,而不是计算机的行为。

5、is-a,has-a,like-a如何应用

如果你确定两件对象之间是is-a的关系,那么此时你应该使用继承;比如菱形、圆形和方形都是形状的一种,那么他们都应该从形状类继承。

如果你确定两件对象之间是has-a的关系,那么此时你应该使用聚合比如电脑是由显示器、CPU、硬盘等组成的,那么你应该把显示器、CPU、硬盘这些类聚合成电脑类

如果你确定两个对象之间是like-a的关系,那么此时你应该使用组合;比如空调继承于制冷机,但它同时有加热功能,那么你应该把让空调继承制冷机类,并实现加热接口

 

 

 

加上 N 代表存入数据库时以 Unicode 格式存储。
N'string' 表示string是个Unicode字符串

Unicode 字符串的格式与普通字符串相似,但它前面有一个 N 标识符(N 代表 SQL-92 标准中的国际语言 (National Language))。N 前缀必须是大写字母。例如,'Michél' 是字符串常量而 N'Michél' 则是 Unicode 常量。Unicode 常量被解释为 Unicode 数据,并且不使用代码页进行计算。Unicode 常量确实有排序规则,主要用于控制比较和区分大小写。为 Unicode 常量指派当前数据库的默认排序规则,除非使用 COLLATE 子句为其指定了排序规则。Unicode 数据中的每个字符都使用两个字节进行存储,而字符数据中的每个字符则都使用一个字节进行存储。有关更多信息,请参见使用 Unicode 数据。

Unicode 字符串常量支持增强的排序规则。

 

 

 

 

 

 

关于SQL SERVER的N前缀的理解

 
复制代码
加N前缀指定后面的字符串为UNICODE常量, SQL Server 的 Unicode 数据类型是基于 SQL-92 标准中的国家字符数据类型。SQL-92 使用前缀字符 N 标识这些数据类型及其值。 
1, Unicode 数据使用 SQL Server 中的 nchar、varchar 和 ntext 数据类型进行存储。对于存1储来源于多种字符集的字符的列,可采用这些数据类型。当列中各项所包含的 Unicode 字符数不同时(至多为 4000),使用 nvarchar 类型。当列中各项为同一固定长度时(至多为 4000 个 Unicode 字符),使用 nchar 类型。当列中任意项超过 4000 个 Unicode字符时,使用 ntext 类型。

在 Microsoft SQL Server  2000 中,传统上非 Unicode 数据类型允许使用由特定字符集定义的字符。字符集是在安装 SQL Server 时选择的,不能更改。使用 非Unicode 数据类型存储数据时,如varchar, char, text等,如果未指定字符排序序列时(字符集),使用默认的字符集,即使为某个字段指定了字符排序序列时,如果SQL Server 默认的排序序列与指定字段的排序序列不同时,不加N的话也会产生乱码,如默认的字符集是单字节的字符集如拉丁字符集(Collation name为Latin1_General_CI_AS)的时候,如果定义Name为Varchar类型,字符集为中文字符集时(Collation name为Chinese_PRC_CI_AS),用如下的插入语句也会乱码

insert a(name) values ('AA中'),因为数据插入的时候,默认还是用Latin1_General_CI_AS字符集送到服务器,再转换为Collation name为Chinese_PRC_CI_AS时,产生乱码,但如果改为如下的时候: insert a(name) values (N'AA中') 则能正确插入,因为通过N前缀,以UNICODE的形式送到SQLSERVER,然后再转换成Chinese_PRC_CI_AS时,就不会产生乱码。

2,UNICODE和非UNICODE之间的转换
2-1 UNICODE--〉非UNICODE:Convert(varchar(50), name Collate Chinese_PRC_CS_AS_KS_WS)--name 是nvarvhar类型的,如name是'AA中'的时候

Select DATALENGTH(Convert(varchar(50), name Collate Chinese_PRC_CS_AS_KS_WS)) from x, 返回的长度为4(UNICODE的时候为6)

2-2 非UNICODE--〉UNICODE的时候:Convert(nvarchar(50), name)--name是varchar类型的时候如name是'AA中'的时候

Select DATALENGTH(Convert(nvarchar(50), name)) from x, 返回的长度为6(非UNICODE的时候为4)

3, 试验归类
测试SQL:
------------------------------------------------------------
drop table a
create table a(a varchar(2))

insert into a values('a')
insert into a values(N'a')
insert into a values('深圳')
insert into a values(N'深圳')
select a, len(a), datalength(a) from a

drop table #a
create table a(a varchar(2))

insert into #a values('a')
insert into #a values(N'a')
insert into #a values('深圳')
insert into #a values(N'深圳')
select a, len(a), datalength(a) from #a

------------------------------------------------------------
drop table a
create table a(a varchar(8000))

insert into a select REPLICATE('a', 8000) 
insert into a select REPLICATE('深', 8000) 
insert into a select REPLICATE(N'a', 8000) 
insert into a select REPLICATE(N'深', 8000) 
select a, len(a), datalength(a) from a


3-1. 字符集是支持双字节的字符集如中文字符集(Collation name为Chinese_PRC_CI_AS)

<1>. 定义varchar(2)

   (1) 正式表
    总结:在中文字符集下,定义varchar(x),
     不论使用不使用N'',英文字符都占1个字节,即可以存x个英文字符;
     不论使用不使用N'',中文字符都占2个字节,即可以存(x / 2)个中文,select结果为汉字本身,不是乱码;
     
   (2) 临时表
    总结:在中文字符集下,定义varchar(x), 
     和正式表表现一样;
  
<2>. 定义nvarchar(2)

   (1) 正式表
    总结:在中文字符集下,定义nvarchar(x),
     不论使用不使用N'',英文字符都占2个字节,即可以存x个英文字符;
     不论使用不使用N'',中文字符都占2个字节,即可以存x个中文,select结果为汉字本身,不是乱码;
     
   (2) 临时表
    总结:在中文字符集下,定义nvarchar(x), 
     和正式表表现一样;
    
<3>. 类型为varchar时,长度 x 和 datalength()对应,都指字节大小;
     英文len() = datalength();
     中文len() = datalength() / 2;
    
    类型为nvarchar时,长度 x 和 len()对应,都指字符长度; 
    
3-2. 字符集是支持单字节的字符集如拉丁字符集(Collation name为Latin1_General_CI_AS)
  
<1>. 定义varchar(2)

   (1) 正式表
    总结:在英文字符集下,定义varchar(x),
     不论使用不使用N'',英文字符都占1个字节,即可以存x个英文字符;
     不论使用不使用N'',中文字符都占1个字节,即可以存x个中文,但只保存前半截中文编码,所以select结果为乱码;
     (特殊:如果使用N'',此时插入的字符数最大为4000)
     英文和中文 len() = datalength();
     
   (2) 临时表
    总结:在英文字符集下,定义varchar(x),
     不论使用不使用N'',英文字符都占1个字节,即可以存x个英文字符;
     不使用N''时,中文占1个字节,可以存x个汉字,但都只存入汉字前半截字符编码,显示为乱码;
     使用N''时,中文占2个字节,只可以存 x/2 个汉字,没有乱码,取出仍为汉字,说明在英文字符集下通过使用N''是可以保存汉字的;
    
     除用N''保存的中文外,其余英文和中文 len() = datalength();
     用N''保存的中文字符len() = datalength() / 2;
    
<2>. 定义nvarchar(2)

   (1) 正式表
    总结:在英文字符集下,定义nvarchar(x),
     不论使用不使用N'',英文字符都占2个字节,即可以存x个英文字符;(注意每个字符比varchar用的空间大)
     不论使用不使用N'',中文字符都占2个字节,即可以存x个中文字符,
     但不使用N''只保存前半截中文编码,所以select结果为乱码;
     使用N''则保存和取出都为汉字本身;
     
   (2) 临时表
    总结:在英文字符集下,定义nvarchar(x), 
     和正式表表现相同;
    
<3>. 类型为varchar时,长度 x 和 datalength()对应,都指字节大小;
     (临时表中N''中文字符长度比较特殊;)
    类型为nvarchar时,长度 x 和 len()对应,都指字符长度; 

4、 使用归类
varchar和nvarchar类型的最大长度,得到以下经验:
<1> 最大长度问题
   1. 在中文字符集下使用varchar,最大长度可定义8000,这个8000是指字节数(datalength()),即最大可以保存8000个英文字符,4000个中文字符;
    特殊:若存入字符N'a',则最大能保存4000个字符,但其所占空间为4000字节;
   2. 在中文字符集下使用nvarchar,最大长度可定义4000,这个4000是指字符个数(len()),即最大可以保存4000个英文字符,4000个中文字符;

   3. 在英文字符集下使用varchar,最大长度可定义8000,这个8000是指字节数(datalength()),由于中文英文都保存为1字节,故最大可以保存8000个英文、中文字符;
   4. 在英文字符集下使用nvarchar,最大长度可定义4000,这个4000是指字符个数(len()),即最大可以保存4000个英文字符,4000个中文字符;
<2> 文字显示问题
   1. N''要和数据类型nvarchar, nchar一起使用,如果对varchar, char字段类型强制使用N'',则会产生一些特殊现象,甚至无法控制; 
   2. 在英文字符集下,想要保存特殊符号字符、中文等双字节字符,在定义表结构时要使用nvarchar或者nchar,在保存时要用N'';
   3. 在中文字符集下,数据库系统缺省已经可以保存特殊符号字符、中文等双字节字符。即使用不使用N'',都按双字节处理。但为了统一期间建议:
    在定义表结构时如果使用nvarchar或者nchar,在保存时要用N'',
    在定义表结构时如果使用varchar和char,此时不要使用N''操作;
   4. SUBSTRING ( expression , start , length ) 
    length:是一个整数,指定子串的长度(要返回的字符数或字节数)。
    中文字符集中按字符数取;
    英文字符集中,char, varchar按字节数取,nchar, nvarchar按字符数取;
复制代码

 

posted @ 2019-03-13 13:20  ~雨落忧伤~  阅读(444)  评论(0编辑  收藏  举报