精华内容
下载资源
问答
  • 变长字符串 varchar varchar(255) 所占资源空间是你存储内容的长度 定长字符串 char char(8...但是 ,还有一种,数据库对定长字段操作有优化,数据量量大时做特定操作时,会比变长字符串快很多。 转载于:https://...

    变长字符串 varchar   varchar(255) 所占资源空间是你存储内容的长度

    定长字符串 char     char(8)不管你存储内容的长度是多少,它所占空间就是8,如果存储内容长度大于8,则会被截取

    所以:varchar相较于char,更能节省资源空间

    但是 ,还有一种,数据库对定长字段操作有优化,数据量量大时做特定操作时,会比变长字符串快很多。

    转载于:https://www.cnblogs.com/yfafa/p/9111661.html

    展开全文
  • 本文主要探讨数据库可变长字符串类型长度设计问题,最好的策略是只分配真正需要的空间,慷慨是不明智的。

    转载请注明原创出处,谢谢!

    HappyFeet的博客

    varchar 类型用于存储可变长字符串,是最常见的字符串数据类型。它比定长类型更节省空间,因为它仅使用必要的空间(例如:越短的字符串使用越少的空间)。

    本文基于 MySQL 数据库进行探讨。

    MySQL 版本为:Server version: 5.7.16 MySQL Community Server (GPL)。


    1、varchar 的长度分配问题

    一直对数据库的可变长字符串的长度分配问题存在疑问:不知道应该分配多长。

    今天我们就来看看 varchar 的长度是依据什么来判断的?

    • 有的人说:“属性有多长,就分配多长”。 ---- 即只分配真正需要的空间

    • 也有人说:“属性的长度应为 4 的倍数,因为这样可以做到内存对齐”。 ---- 即分配为 4 的倍数的长度,可以内存对齐

    • 另一些极端的人觉得:“既然对于 varchar 来说,越短的字符串使用越少的空间,那么这个长度定大一些也不会有什么问题,都分配 4000 的长度,这样可以避免出现超过长度的数据存不进去的问题”,即不管属性长度如何,都分配一个很大的长度,例如:4000.

    那到底哪一种说法是对的呢?

    我们来看个例子,假设我们要建一张表来存 CSDN 个人资料中的三条属性:昵称、地区和简介。下面有三个版本的建表语句,分别针对不同的说法所创建的。

    -- 版本 1:只分配真正需要的空间
    create table user_info (
    	user_id 		long primary key,
    	nickname 		varchar(20),
    	region   		varchar(100),
    	introduction 	varchar(500)
    );
    
    -- 版本 2:在版本 1 的基础上调整为 4 的倍数
    create table user_info (
    	user_id 		long primary key,
    	nickname 		varchar(32),
    	region   		varchar(128),
    	introduction 	varchar(512)
    );
    
    -- 版本 3:长度都取 4000
    create table user_info (
    	user_id 		long primary key,
    	nickname 		varchar(4000),
    	region   		varchar(4000),
    	introduction 	varchar(4000)
    );
    

    经过查阅众多资料之后,得出结论:版本 1 是最好的,即只分配真正需要的空间

    2、结论分析

    下面就来说一下为什么:

    (1)varchar 需要 1 或 2 个额外字节记录字符串的长度

    如果列的最大长度小于或等于 255 字节,则只使用 1 个字节表示,否则使用 2 个字节。假设采用 latin1 字符集,一个 varchar(10) 的列需要 11 个字节的存储空间。varchar(1000) 的列则需要 1002 个字节,因为需要 2 个字节存储长度信息。

    (2)内存对齐 确实有一定的性能提升,但是通过将字段长度定义为 4 的倍数做不到内存对齐

    对于 varchar 类型来说,字符串是变长的,它的实际存储长度为:1 或 2 个额外字节 + 字符串实际长度。举几个例子:

    a、往 varchar(8) 中存入 "abcdefgh",实际存储长度应该为 1 + 8 = 9 个字节,第一个字节记录这个字符串的长度;

    b、往 varchar(8) 中存入 "abc",实际存储长度为 1 + 3 = 4 个字节。

    c、往 varchar(1000) 中存入 "abc",实际存储长度为 2 + 3 = 5 个字节。

    说到内存对齐就简单提一下 MySQL 存储引擎 InnoDB 的数据页结构:page 是 MySQL 管理存储空间的基本单位,它由一条或多条 row 组成,row 就对应于 table 的一条记录,数据读取也是基于 page 来的,而不是一行一行的读。更多详情见:InnoDB数据页结构

    (3)MySQL 在解决某些类型的查询时需要创建隐式临时表(又分为内存临时表和磁盘临时表)

    对于临时表中的字段,MySQL 都会分配一个足够长的定长空间来存放。这个定长空间必须足够长以容纳其中最长的字符串,例如,如果是 varchar 列则需要分配其完整长度,如果使用 UTF-8 字符集,那么 MySQL 将会为每个字符预留三个字节。

    假设我们在查询 user_info 的时候触发了隐式临时表的创建,对于 nickname 这一列,如果我们使用版本 1的建表语句,MySQL 按照完整长度,每条记录仅需要分配 20 的内存,而如果是版本 3的话,每条记录却需要分配 4000 的长度!!!很明显,这是一个非常糟糕的设计。

    MySQL 在以下几种情况会创建临时表(不过这不是本文的重点!)

    • UNION 查询;

    • 用到 TEMPTABLE 算法或者是 UNION 查询中的视图;

    • ORDER BY 和 GROUP BY 的子句不一样时;

    • 表连接中,ORDER BY 的列不是驱动表中的;

    • DISTINCT 查询并且加上 ORDER BY 时;

    • SQL 中用到 SQL_SMALL_RESULT 选项时;

    • FROM 中的子查询;

    • 子查询或者 semi-join 时创建的表;

    (4)预分配内存空间的问题

    注意,这一点存疑!这个说法我目前还没有找到具体的源码或文档说明,不过如果有预分配内存的话,那应该是说得通的,待找到依据再对这一点进行更新

    这个和第三点有点类似,只是第三点讲的是在数据库内部引擎中,而这里讲的是客户端从数据库引擎获取数据。简单来说就是,对于一个 varchar(1000),客户端的 executor 在没拿到存储引擎存储的数据之前,并不会知道我这一行拿出来的数据到底有多长,可能长度只有 1,可能长度是 800,那怎么办呢,那就只能先把最大空间分配好了,避免放不下的问题发生,这样实际上对于真实数据较短的 varchar 确实会造成空间的浪费。举例:如果我有 1000 个 varchar(1000),但是每个只存一个字符,那么真实数据量其实只有 1K,但是我却需要 1M 的内存去适应它。

    (5)字段长度能够起到一定的约束作用

    比如一个字段长度最大不超过 10 个字节,那我们就可以将其设置为 varchar(10),如果超过了 10 个字节,就说明这是个脏数据,这对实际数据能起到一定的约束。

    (6)数据库对于索引的字段长度有限制,在长的数据列上建索引可能会报错,例如

    mysql> create table long_length_table(
        -> long_column1 varchar(2000),
        -> long_column2 varchar(2000),
        -> long_column3 varchar(2000),
        -> long_column4 varchar(2000),
        -> long_column5 varchar(2000)
        -> );
    Query OK, 0 rows affected (0.02 sec)
    
    mysql> create table short_length_table(
        -> short_column1 varchar(10),
        -> short_column2 varchar(10),
        -> short_column3 varchar(10),
        -> short_column4 varchar(10),
        -> short_column5 varchar(10)
        -> );
    Query OK, 0 rows affected (0.03 sec)
    
    mysql> create index short_length_table_idx on short_length_table(short_column1, short_column2, short_column3, short_column4);
    Query OK, 0 rows affected (0.02 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    mysql> create index long_length_table_idx on long_length_table(long_column1, long_column2, long_column3, long_column4);
    ERROR 1071 (42000): Specified key was too long; max key length is 3072 bytes
    

    3、总结

    在 varchar(30) 和 varchar(1000) 存入 “ab”,使用的存储空间区别不大,无非就是一个使用 1 个字节记录字符串的长度,另一个使用 2 个字节记录。但是对于在某些 case 下,varchar(1000) 的性能会比 varchar(30) 差很多,内存消耗也会成倍增加。

    另外,将长度调整为 4 的倍数(内存对齐)会提高性能这种说法也是不对的。

    所以得出的结论是: 只分配真正需要的空间

    PS:以后终于可以理直气壮的跟别人讲:varchar 的长度不宜过长,满足长度要求即可;也不必强行将长度设置成 4 的倍数,这对性能提升是没有效果的。_

    参考资料:

    (1)《高性能 MySQL》第三版.

    (2)MySQL - varchar length and performance

    (3)What are the current best practices concerning varchar sizing in SQL Server?

    (4)Best practices for SQL varchar column length

    (5)Would using varchar(5000) be bad compared to varchar(255)?

    (6)What are the optimum varchar sizes for MySQL?

    (7)MySQL: Disk Space Exhaustion for Implicit Temporary Tables

    (8)File Space Management

    (9)InnoDB数据页结构

    展开全文
  • SELECT id, rownum FROM test ORDER BY RIGHT(REPLICATE('0',10)+CAST(rownum AS varchar(10)),10) ASC ...2.使用RIGHT方法,格式化字符串,如上述代码所示,假设rownum字段长度为10,数据中包...
    SELECT id, rownum
        FROM test
        ORDER BY RIGHT(REPLICATE('0',10)+CAST(rownum AS varchar(10)),10) ASC

    说明:

    1.不建议转换成数字类型在order by,因为数据存在字符时,可能转换失败。

    2.使用RIGHT方法,格式化字符串,如上述代码所示,假设rownum字段长度为10,数据中包含'1','11','tt',转换后为'0000000001','0000000011','00000000tt'

    展开全文
  • sqlserver中变长字符串与定长字符串

    千次阅读 2018-11-08 13:35:10
    最近做一个工厂的自动化项目使用到sqlserver,查询其中某个值的时候返回的是空值,研究了一下发现该值的类型是nchar,定unicode编码,网上查了下nchar和nvarchar的区别,nvarchar类型存储时会按字长实际长度两倍...

    最近做一个工厂的自动化项目使用到sqlserver,查询其中某个值的时候返回的是空值,研究了一下发现该值的类型是nchar,定长unicode编码,网上查了下ncharnvarchar的区别,nvarchar类型存储字节数为字长实际长度两倍(unicode编码),进一步通过程序验证发现nchar(l)存储时按开辟空间的长度进行存储的(也是unicode编码,字节数为2*l),余位会补空,读取到C#中该值长度是l而不是实际长度。以下是测试代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Data.SqlClient;
    using System.Data;
    
    namespace ConsoleApplication2
    {
        class Program
        {
            static void Main(string[] args)
            {
                string connectionString = "server=;database=;user=;password=";
                using (SqlConnection con = new SqlConnection(connectionString))
                {
                    try
                    {
                        con.Open();
                    }
                    catch (SqlException e)
                    {
                        throw e;
                    }
                    if (con.State == ConnectionState.Open)
                    {
                        string insertCmd = $"insert into InvoiceCardState(ChrBoxUp,ChrLot) values('KS','KS')";
                        int rows=ExecuteSql(insertCmd, con);
    
                        DataTable dt = new DataTable();
                        if(rows>0)
                        {
                            string queryCmd = $"select * from Test where ChrBoxUp='KS'";
                            QuerySql(queryCmd, con, dt);
                            if(dt.Rows.Count>0)
                            {
                                string lot = dt.Rows[0]["ChrLot"].ToString();
                                string pb = dt.Rows[0]["ChrBoxUp"].ToString();
                                int lotl = lot.Length;
                                int pbl = pb.Length;
                                Console.WriteLine("lot length:" + lotl.ToString());
                                Console.WriteLine("pb length:" + pbl.ToString());
                            }
                        }
                    }
    
                }
            }
    
            static int ExecuteSql(string sqlcmd, SqlConnection con)
            {
                int rows = 0;
                SqlCommand cmd = new SqlCommand(sqlcmd, con);
                try
                {
                    rows = cmd.ExecuteNonQuery();
                }
                catch (SqlException e)
                {
                    throw e;
                }
                return rows;
            }
    
            static int QuerySql(string sqlcmd, SqlConnection con, DataTable dt)
            {
                int errorCode = 0;
                SqlCommand cmd = new SqlCommand(sqlcmd, con);
                using (SqlDataAdapter adpter = new SqlDataAdapter(cmd))
                {
                    try
                    {
                        adpter.Fill(dt);
                    }
                    catch (SqlException e)
                    {
                        errorCode = e.ErrorCode;
                    }
                }            
                return errorCode;
            }
        }
    }
    

    其中Test表中ChrBoxUpnvarchar(12)ChrLot类型为nchar(12),均存入字段KS,然后读取,结果ChrLot长度度为12,ChrBoxUp长度为2,加断点监视string lot的值KS右端存在一部分空格,并且如果将查询条件改为where ChrLot='KS',查询结果为空,如果需要查询可以用where rtrim(ChrLot)='KS'进行查询。

    展开全文
  • 字符串类型用于存储字符和字符串数据,主要包含三种具体的类型:定长字符串、变长字符串以及字符串大对象。各种数据库对于字符串类型的支持如下: 数据类型 Oracle MySQL SQL Server PostgreSQL 定长字符串 ...
  • 字符串类型的字段在各关系数据库中均占有重要地位。比如Oracle数据库中用于存储字符串类型数据的字段类型就超过了5种。遗憾的是,在日常工作中笔者发现很多开发者对这些类型并没有完整的认识,更不用说设计表结构时...
  • 现代数据库一般都支持CHAR与VARCHAR字符型字段类型,CHAR是用来保存定长字符,存储空间的大小为字段定义的长度,与实际字符长度无关,当输入的字符小于定义长度时最后会补上空格。VARCHAR是用来保留变长字符,在...
  • 存储英文字符字段类型用什么?

    千次阅读 2012-05-31 11:04:53
    char、varchar、text和nchar、...中文字符存储到SQL Server中会保存为两个字节(一般采用Unico编码),英文字符保存到数据库中,如果字段的类型为varchar,则只会占用一个字节,而如果字段的类型为nvarchar,则会占用
  • mysql存储最大字段数,长度含义

    万次阅读 2017-12-11 12:07:36
    mysql最大字段数 一直对mysql最大字段数不明确有人说是1024 还有人说 Max columns per row 4096  InnoDB is limited to 1000 columns 实践是检验真理的唯一方法 mysql> use test; ...
  • mysql中如何使用合适的字段字段长度

    万次阅读 多人点赞 2018-11-11 20:40:33
    下面是mysql一个字段中含有哪些信息 ...1、整数的数值类型已经限制了取值范围,有符号整型和无符号整型都有,而M值并不代表可以存储的数值字符长度,它代表的是数据在显示时显示的最小长度; 2、当存储...
  • mysql中字段类型及字符

    千次阅读 2016-11-23 20:09:23
    介绍数据库中常用字段类型 标识符的字符 SQL语句分类 字符字符集概述 Mysql支持的字符集简介 Unicode简述 怎样选择合适的字符集 Mysql字符集的设置mysql 字符集和校验规则 排列规则总结介绍数据库中常用字段类型...
  • Oracle字段类型

    2008-11-21 08:59:00
    Oracle字段类型Char 用于描述定长的字符型数据,长度varchar2 用于描述变长的字符型数据,长度nchar 用来存储Unicode字符集的定长字符型数据,长度nvarchar2 用来存储Unicode字符集的变长字符型数据,长度number ...
  • SQL SERVER怎样建立备注型字段

    千次阅读 2011-08-15 11:19:41
    SQL SERVER怎样建立备注型字段?     SQL SERVER怎样建立备注型字段?     用text就可以了,或着用ntext! varchar不能超过2
  • NSString字符串截取的三种方法,截取目标字段
  • Mysql 字段类型长度

    千次阅读 2020-07-14 17:00:33
    1.整数 int(11)、tinyint(4)、smallint(6)、mediumint(9)、bigint(20) 1、整数的数值类型已经限制了取值范围,有符号整型和无符号整型都有, 而M值并不代表可以存储的数值字符长度,它代表的是数据在显示时...
  • 简要描述一下SQL中的五种数据类型:字符型,文本型,数值型,逻辑型和日期型 字符型  VARCHAR VS CHAR  VARCHAR型和CHAR型数据的这个差别是细微的,但是非常重要。他们都是用来储存字符串长度小于255的字符...
  • VARCHAR VS CHARVARCHAR型和CHAR型数据的这个差别是细微的,但是非常重要。他们都是用来储存字符串长度小于255的字符。... 现在假如你把字符串输入一个长度为四十个字符的CHAR型字段中,那么当你取出数
  • oracle字段类型

    千次阅读 2009-08-05 10:18:00
    Char 用于描述定长的字符型数据,长度varchar2 用于描述变长的字符型数据,长度nchar 用来存储Unicode字符集的定长字符型数据,长度nvarchar2 用来存储Unicode字符集的变长字符型数据,长度number 用来存储整型或者...
  • 数据库字段的长度 作用

    万次阅读 2017-08-04 10:09:55
    数据库字段的长度 指的是字节 作用:如果不指定长度,数据库在存储的时候都必须给每个字段预留最大的存储空间,这样极大的浪费了空间,也加大了数据库本身管理的...CHAR存储定数据很方便,CHAR字段上的索引效率级
  • 1、字段类型 Integer int整型,普通整数,一般是32位 SmallInteger int 取值范围最小的整型,一般是16位 ...Text str文本 变长字符串,对较大或不限长度的字符串做了优化 Unicode unicode变长unicode字符串 ...
  • 对于程序中的string型字段,SQLServer中有char、varchar、nchar、nvarchar四种类型来对应(暂时不考虑text和ntext),开建立数据库中,对这四种类型往往比较模糊,这里做一下对比。 定长或变长 所谓定长就是...
  • mysql对于字符列的索引方案

    千次阅读 2018-02-27 18:19:55
    1.模拟哈希索引 新建一列用于存储该字符列的hash值(哈希函数不要使用SHA1(),MD5(),因为会产生很字符串,浪费空间,比较也慢,最好是返回整数的hash函数),在该列建立索引,查询时必须在where子句中包含常量值...
  • SQLServer中有char、varchar、nchar、nvarchar四种类型来对应(char、varchar、nchar、nvarchar特点比较) CHAR char存储定长数据很方便,CHAR字段上的索引效率级高,比如...varchar存储变长数据,但存储效率没有CHAR高
  • mysql 字段长度限制

    万次阅读 2016-10-26 17:41:18
    变长字段,长度为0~65 535个字符 TINYTEXT String长度+1字节 字符串,最大长度为255个字符 TEXT String长度+2字节 字符串,最大长度为65 535个...
  • 昨天在写入SQLServer数据库的时候有一张表把所有的数据字段都写成了VARCHAR类型了,这样的好处就是很简单,出错概率小,麻烦就是如果我要依据一个字段:比如说人的年龄排序的时候就会出错,这里默认都是字符类型的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 94,507
精华内容 37,802
关键字:

对于变长字符型字段