凡是有但是-varchar和nvarchar的初步学习之一


背景

高应用开发, 在涉及到国内国外的问题时,重要的事情有两个:
时区转换, 字符集转换. 时区转换虽然是很难理清楚, 各种规范不统一的事情
但是字符集转换更加扯淡. 如果是一种数据库,一种字符集可能还好说
现在面临的是 多种数据库: 开源,商业,信创,分布式...
这时候就已经是一头雾水了.
自己虽然看了一阵子, 但是依旧是迷迷糊糊的.
所以想先总结一下, 希望后续能够慢慢的将内容夯实

varchar和nvarchar

数据库有varchar和nvarchar
其实一个比较重的区别是:
部分数据库 varchar 后面的数字指的是 这个字段能够存储的字节数.
nvarchar 后面的数字, 基本上指的是能够存储的字符数. 这里就有一个 凡是有但是.
Mysql8数据库虽然有 varcahr和nvarcahr, 但是他计算长度限制是按照字符数来进行计算.
所以就引入了 mysql utf8mb3 和 utf8mb4 下数据库varcahr总长度限制的问题. 另外神通数据库有这么一个参数, 可以指定varchar的长度限制.
DEFAULT_VARCHAR_LEN=1
会改变varchar的存储情况.

Oracle和MySQL的限制问题

SQLServer的限制: 注意我的排序规则是 chinese_prc_ci_as
varchar时:
消息 131,级别 15,状态 2,第 6 行
The size (8001) given to the column 'zhaobsh' exceeds the maximum allowed for any data type (8000).
nvarchar时:
消息 2717,级别 16,状态 2,第 7 行
The size (8000) given to the parameter 'zhaobsh' exceeds the maximum allowed (4000). 数据库会有一些底层的限制 Oracle数据库一开始与SQLServer的限制是一样的
也是在ZHS16GBK的字符集 varchar(8000) nvarchar(4000)
但是Oracle19c 时进行了一定程度的扩张:
32767 bytes if MAX_STRING_SIZE = EXTENDED
4000 bytes if MAX_STRING_SIZE = STANDARD 但是据说这个参数修改起来很麻烦:
数据库需要 startup UPGRADE 以升级模式启动,
然后才能修改参数,
alter system set MAX_STRING_SIZE = EXTENDED scope=spfile;
并且需要跑脚本 utl32k.sql,
然后关闭数据库再正常重启数据库。 注意这里面有一个深坑, 如果不改这个参数 oracle12c 以后可以创建一个 3万多长度的varchar列
但是插入数据时 就会被截断到 4000 / 80000 的长度.

关于字符编码

需要说明, 字符集是字符集, 字符编码格式是字符编码格式.
只不过国内的 GB2312 GBK GB18030 既是字符集,又是编码格式.
所以很多人有所混淆. unicode 是字符集, 用来进行全世界所有字符的展示
utf-8 是编码格式,用于计算机系统进行存储.
utf-16 utf-32 是另外两种编码格式, 不通电是针对字符长度的限制是不一样的.

字符编码的特点

广义的 Unicode 是一个标准,定义了一个字符集以及一系列的编码规则,
即 Unicode 字符集和 UTF-8、UTF-16、UTF-32 等等编码…… Unicode 字符集为每一个字符分配一个码位,例如「知」的码位是 30693,记作 U+77E5(30693 的十六进制为 0x77E5)。
UTF-8 顾名思义,是一套以 8 位为一个编码单位的可变长编码。会将一个码位编码为 1 到 4 个字节: U+ 0000 ~ U+ 007F: 0XXXXXXX
U+ 0080 ~ U+ 07FF: 110XXXXX 10XXXXXX
U+ 0800 ~ U+ FFFF: 1110XXXX 10XXXXXX 10XXXXXX
U+10000 ~ U+1FFFF: 11110XXX 10XXXXXX 10XXXXXX 10XXXXXX 根据上表中的编码规则,之前的「知」字的码位 U+77E5 属于第三行的范围: 7 7 E 5
0111 0111 1110 0101 二进制的 77E5
--------------------------
0111 011111 100101 二进制的 77E5
1110XXXX 10XXXXXX 10XXXXXX 模版(上表第三行)
11100111 10011111 10100101 代入模版
E 7 9 F A 5 这就是将 U+77E5 按照 UTF-8 编码为字节序列 E79FA5 的过程。反之亦然。

varchar与nvarchar解决的问题

varchar 应该只是按照数据库的字符集进行文件的存储, 只能够存储编码格式,字符集,排序规则内的字符
无法保存非自己字符集内的字符. nvarchar 则是将字符按照unicode 等格式进行保存.
这样的话, 能够保证非标准字符集支持的字符进行展示. 一定程度下可以实现国际化多语的需求.

其他数据库的情况

PG数据库没有 nvarchar
他的字符类型就是 varchar char 还有 text
他应该默认使用utf8国际化支持, 然后 数字表示的是字符长度. mysql数据库 有nvarchar的类型
但是他的varchar 也是按照字符进行存储, 理论上也是字符, 不是字节.
mysql的坑在于 utf8mb3和 utf8mb4 国产数据库里面要看支付的字符集.
国产信创必须要支持GB18030字符集.
但是GB18030与UTF8应该不是严格意义上的子集和超集的关系
所以很多表现也与字符集有关系. UTF8的出现其实比很多数据库的出现要晚一些.
SQLServer其实到了2019的版本才严格支持 utf8
因为微软的国际化做的其实比utf8要更久和更踏实, 其实sqlserver的历史包袱也是最大的.

凡是有但是-varchar和nvarchar的初步学习之一的更多相关文章

  1. sql中NVARCHAR(MAX) 性能和占空间分析 varchar(n),nvarchar(n) 长度性能及所占空间分析

    varchar(n),nvarchar(n) 中的n怎么解释: nvarchar(n)最多能存n个字符,不区分中英文. varchar(n)最多能存n个字节,一个中文是两个字节. 所占空间: nvar ...

  2. 答:SQLServer DBA 三十问之一: char、varchar、nvarchar之间的区别(包括用途和空间占用);xml类型查找某个节点的数据有哪些方法,哪个效率高;使用存储 过程和使用T-SQL查询数据有啥不一样;

    http://www.cnblogs.com/fygh/archive/2011/10/18/2216166.html 1. char.varchar.nvarchar之间的区别(包括用途和空间占用) ...

  3. varchar(n),nvarchar(n) 长度、性能、及所占空间的说明

    varchar(n),nvarchar(n) 中的n怎么解释: nvarchar(n)最多能存n个字符,不区分中英文. varchar(n)最多能存n个字节,一个中文是两个字节. 所占空间: nvar ...

  4. varchar和Nvarchar区别

    http://www.cnblogs.com/yelaiju/archive/2010/05/29/1746826.html Unicode字符集就是为了解决字符集这种不兼容的问题而产生的,它所有的字 ...

  5. sql-char和varchar,nvarchar的区别

    数据类型的比较 char表示的是固定长度,最长n个字 varchar表示的是实际长度的数据类型 比如:如果是char类型,当你输入字符小于长度时,后补空格:而是varchar类型时,则表示你输入字符的 ...

  6. [转]varchar(n),nvarchar(n) 长度、性能、及所占空间分析

    varchar(n),nvarchar(n) 中的n怎么解释: nvarchar(n)最多能存n个字符,不区分中英文. varchar(n)最多能存n个字节,一个中文是两个字节. 所占空间: nvar ...

  7. varchar与nvarchar的区别

    nvarchar可变长度的Unicode字符数据 varchar可变长度且非 Unicode 的字符数据 举例: varchar(1)   --可以插进入一个数字或者一个字母,如果要插入一个汉字改为v ...

  8. sql server varchar和nvarchar的区别

    一.前言 在了解varchar 和nvarchar之前咱们先了解一下这些词的字面和常用意思,以方便我们更好的使用: SQL SERVER中生成的语句中,字符串前加N.N 前缀必须是大写字母.是Unic ...

  9. varchar(n),nvarchar(n) 长度、性能、及所占空间分析 nvarchar(64) nvarchar(128) nvarchar(256)(转)

    varchar(n),nvarchar(n) 中的n怎么解释: nvarchar(n)最多能存n个字符,不区分中英文. varchar(n)最多能存n个字节,一个中文是两个字节. 所占空间: nvar ...

  10. char、varchar和nvarchar的区别

    首先char.varchar和nvarchar.text.ntext都是数据库中的文本数据类型,再区分区分var前缀.n前缀的区别.而text.ntext已经普遍被varchar(MAX)和nvarc ...

随机推荐

  1. 如何从零开始实现TDOA技术的 UWB 精确定位系统(2)

    这是一个系列文章<如何从零开始实现TDOA技术的 UWB 精确定位系统>第2部分. 重要提示(劝退说明): Q:做这个定位系统需要基础么?A:文章不是写给小白看的,需要有电子技术和软件编程 ...

  2. Docker 部署工具

    Docker 容器的创建比较简单,容器解决了应用程序对于运行环境的依赖问题,但是在当前所处的微服务盛行的情况下,手动管理容器是一件比较重复其及其枯燥的工作,这项工作理论上可以通过计算机来完成,因此涌现 ...

  3. 04 链表(上):如何实现LRU缓存淘汰算法?

    一.什么是链表? 1.和数组一样,链表也是一种线性表. 2.从内存结构来看,链表的内存结构是不连续的内存空间,是将一组零散的内存块串联起来,从而进行数据存储的数据结构. 3.链表中的每一个内存块被称为 ...

  4. Provider MVVM架构

    MVVM架构分为M(Model).V(View).VM(ViewModel)三个部分,他们分别处理自己的分工,在View和Model之间使用ViewModel作为中介者,使View和Model不受业务 ...

  5. Prometheus 快速入门

    Prometheus&Grafana快速入门 一.prometheus简介 prometheus是监控多个大数据组件的监控系统.Prometheus是由SoundCloud开发的开源监控报警系 ...

  6. MySQL篇:bug2_ Navicate无法添加或更新子行-外键约束失败

    问题产生原因 Mysql中如果表和表之间建立的外键约束,则无法删除表及修改表结构. 解决办法 解决方法是在Mysql中取消外键约束: SET FOREIGN_KEY_CHECKS=0; 再添加值, 然 ...

  7. 从部署和运维说说DLI(1)

    DLI是支持多模引擎的Serverless大数据计算服务,其很好的实现了Serverless的特性:   1. 弱化了存储和计算之间的联系: 2. 代码的执行不再需要手动分配资源: 3. 按使用量计费 ...

  8. 云图说|图解DGC:基于华为智能数据湖解决方案的一体化数据治理平台

    摘要:数据湖治理中心DGC,帮助企业快速构建从数据集成到数据服务的端到端智能数据系统,消除数据孤岛,统一数据标准,加快数据变现,实现数字化转型. 本文分享自华为云社区<[云图说]第232期 图解 ...

  9. Git 工具 - 子模块: submodule与subtree的使用

    git日常使用中,基本都是一个项目一个Git仓库的形式,那么当我们的代码中碰到了业务级别的需要复用的代码,我们一般怎么做呢? 比如:某个工作中的项目需要包含并使用另一个项目. 也许是第三方库,或者你独 ...

  10. storybook组件属性详解:组件props到strorybook Args

    首先我们查看官方文档:https://storybook.js.org/docs/vue/writing-docs/doc-block-argstable#customizing 官方的例子么有看到v ...