背景
MySQL 一直以来都有 TEXT、BLOB 等类型用来存储、视频等大对象信息。比如一张,随便一张都 5M 以上。视频也是,随便一部视频就是 2G 以上。
假设用 MySQL 来存放**视频等信息,一部是 2G,那么存储 1000 部就是 2TB,2TB 也就是 1000 条记录而已,但是对数据库性能来说,不仅仅是看记录数量,更主要的还得看占用磁盘空间大小。空间大了,所有以前的经验啥的都失效了。
所以一般来说存放这类信息,也就是存储他们的存放路径,至于文件本身存放在哪里,那这就不是数据库考虑的范畴了。数据库只关心怎么来的快,怎么来的小。
举例
虽然不推荐 MySQL 这样做,但是也得知道 MySQL 该怎么做才行,做到心里有数。比如下面一张微信,大概 5M 的样子。
root@ytt:/var/lib/mysql-files# ls -sihl 微信_20190711095019jpg274501 54M -rw-r--r-- 1 root root 54M Jul 11 07:17 微信_20190711095019jpg
拷贝 100 份这样的来测试
root@ytt:/var/lib/mysql-files# for i in `seq 1 100`; do cp 微信_20190711095019jpg "$i"jpg;done;
root@ytt:/var/lib/mysql-files# ls
100jpg 17jpg 25jpg 33jpg 41jpg 4jpg 58jpg 66jpg 74jpg 82jpg 90jpg 99jpg f8tsv
10jpg 18jpg 26jpg 34jpg 42jpg 50jpg 59jpg 67jpg 75jpg 83jpg 91jpg 9jpg 微信_20190711095019jpg
1111jpg 19jpg 27jpg 35jpg 43jpg 51jpg 5jpg 68jpg 76jpg 84jpg 92jpg f1tsv
11jpg 1jpg 28jpg 36jpg 44jpg 52jpg 60jpg 69jpg 77jpg 85jpg 93jpg f2tsv
12jpg 20jpg 29jpg 37jpg 45jpg 53jpg 61jpg 6jpg 78jpg 86jpg 94jpg f3tsv
13jpg 21jpg 2jpg 38jpg 46jpg 54jpg 62jpg 70jpg 79jpg 87jpg 95jpg f4tsv
14jpg 22jpg 30jpg 39jpg 47jpg 55jpg 63jpg 71jpg 7jpg 88jpg 96jpg f5tsv
15jpg 23jpg 31jpg 3jpg 48jpg 56jpg 64jpg 72jpg 80jpg 89jpg 97jpg f6tsv
16jpg 24jpg 32jpg 40jpg 49jpg 57jpg 65jpg 73jpg 81jpg 8jpg 98jpg f7tsv
我们建三张表,分别用 LONGBLOB、LONGTEXT 和 VARCHAR 来存储这些信息
mysql> show create table tt_image1G
1 row
Table: tt_image1
Create Table: CREATE TABLE `tt_image1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`image_file` longblob,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (000 sec)
mysql> show create table tt_image2G
1 row
Table: tt_image2
Create Table: CREATE TABLE `tt_image2` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`image_file` longtext,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (000 sec)
mysql> show create table tt_image3G
1 row
Table: tt_image3
Create Table: CREATE TABLE `tt_image3` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`image_file` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (000 sec)
我们来给三张表插入 100 张(插入前,建议把 max_allowed_packet 设置到最大)
tt_image1
root@ytt:/var/lib/mysql-files# for i in `seq 1 100`;
do mysql -S /var/run/mysqld/mysqldsock -e "insert into ytttt_image1(image_file)
values (load_file('/var/lib/mysql-files/$ijpg'))";done;
tt_image2
root@ytt:/var/lib/mysql-files# for i in `seq 1 100`;
do mysql -S /var/run/mysqld/mysqldsock -e "insert into ytttt_image2(image_file)
values (hex(load_file('/var/lib/mysql-files/$ijpg')))";done;
tt_image3
root@ytt:/var/lib/mysql-files# aa='begin;';for i in `seq 1 100`;
do aa=$aa"insert into ytttt_image3(image_file) values
('/var/lib/mysql-files/$ijpg');";
done;aa=$aa'commit;';mysql -S /var/run/mysqld/mysqldsock -e "`echo $aa`";
检查下三张表记录数
mysql> select 'tt_image1' as name ,count() from tt_image1 union allselect 'tt_image2',count() from tt_image2 union all select 'tt_image3', count() from tt_image3;+-----------+----------+| name | count() |+-----------+----------+| tt_image1 | 100 || tt_image2 | 100 || tt_image3 | 100 |+-----------+----------+3 rows in set (000 sec)看下文件大小,可以看到实际大小排名,LONGTEXT 字段存储的最大,LONGBLOB 字段缩小到一半,最小的是存储路径的表 tt_image3。所以这里从存储空间来看,存放路径最占优势。
root@ytt:/var/lib/mysql/ytt# ls -silhS tt_image274603 11G -rw-r----- 1 mysql mysql 11G Jul 11 07:27 tt_image2ibd274602 545M -rw-r----- 1 mysql mysql 544M Jul 11 07:26 tt_image1ibd274605 80K -rw-r----- 1 mysql mysql 112K Jul 11 07:27 tt_image3ibd那么怎么把取出来呢?
tt_image3 肯定是最容易的
mysql> select from tt_image3;+----+----------------------------+| id | image_file |+----+----------------------------+| 1 | /var/lib/mysql-files/1jpg |+----+----------------------------+100 rows in set (000 sec)tt_image1 直接导出来二进制文件即可,下面我写了个存储过程,导出所有。
mysql> DELIMITER $$mysql> USE `ytt`$$mysql> DROP PROCEDURE IF EXISTS `sp_get_image`$$mysql> CREATE DEFINER=`ytt`@`localhost` PROCEDURE `sp_get_image`()mysql> BEGIN DECLARE i,cnt INT DEFAULT 0; SELECT COUNT() FROM tt_image1 WHERE 1 INTO cnt; WHILE i < cnt DO SET @stmt = CONCAT('select image_file from tt_image1 limit ',i,',1 into dumpfile ''/var/lib/mysql-files/image',i,'jpg'''); PREPARE s1 FROM @stmt; EXECUTE s1; DROP PREPARE s1; SET i = i + 1; END WHILE; END$$mysql> DELIMITER ;mysql> call sp_get_image;tt_image2 类似,把 select 语句里 image_file 变为 unhex(image_file) 即可。
总结
这里我举了个用 MySQL 来存放的例子,总的来说有以下三点:
占用磁盘空间大(这样会带来各种各样的功能与性能问题,比如备份,写入,读取 *** 作等)
使用不易
还是推荐用文件路径来代替实际的文件内容存放
如果是路径用nvarchar,如果转化成二进制存进数据库用binary,数据库中还有一个是image类型。数据库有很多种类型,从最简单的存储有各种数据的表格到能够进行海量数据存储的大型数据库系统都在各个方面得到了广泛的应用。
因为涉及到固定电话,所以一般用varchar2 ,单纯手机号码的话可以用number。
数据类型分类:
1、数字型— Integer(整型)、Long(长整型)、Single(单精度浮点型)、Double(双精度浮点型)和 Currency(货币型)。
2、字节型
3、文本型——String 类型。
用CHAR和VARCHAR都可以存储,如果是比较长的英语文章还可以用各类数据库提供的大字符类型进行储存
CHAR类型:定长字符串 可以储存指定长度范围类得字符串,不足的用空格补齐
VARCHAR类型:变长字符串 可以储存指定长度范围类得字符串,长度可变
数据库并不是直接存储文件的。数据库依照某种数据模型组织起来并存放二级存储器中的数据集合。这种数据集合具有如下特点:尽可能不重复,以最优方式为某个特定组织的多种应用服务,其数据结构独立于使用它的应用程序,对数据的增、删、改和检索由统一软件进行管理和控制。数据库你可以想象为一大堆数据表的集合,数据就存放在每个表中,文件等也能存放在数据库的表中,不过需要转换成二进制编码以数据的格式存放,需要取出时再通过程序进行转换成为原来的格式比如留言板,你看到的内容是存放在数据库的一个记录表中,一条留言就占用一条记录行,需要时通过SELECT 等语句读取出它的内容,显示出来内容更新了,也通过UPDATE 等语句更新数据库中相应记录行的数据
数据库中一般的数字类型都可以存储负数,如int,numeric,decimal等。
工具:sqlserver 2008 R2
步骤:
1、以int类型为例,首先创建一个表:
2、在表中分别插入正数、负数和零。
3、执行后结果:
大型文本数据可以采用文本或图形二进制的数据类型:
1、TEXT
TEXT数据类型用于存储大量文本数据,其容量理论上为1 到2的31次方-1 (2, 147, 483, 647)个字节,在实际应用时需要视硬盘的存储空间而定。
SQL Server 2000 以前的版本中,数据库中一个TEXT 对象存储的实际上是一个指针,它指向一个个以8KB (8192 个字节)为单位的数据页(Data Page)。 这些数据页是动态增加并被逻辑链接起来的。在SQL Server 2000 中,则将TEXT 和IMAGE 类型的数据直接存放到表的数据行中,而不是存放到不同的数据页中。 这就减少了用于存储TEXT 和IMA- GE 类型的空间,并相应减少了磁盘处理这类数据的I/O 数量。
2、NTEXT
NTEXT数据类型与TEXT类型相似不同的,是NTEXT 类型采用UNICODE 标准字符集(Character Set), 因此其理论容量为230-1(1, 073, 741, 823)个字节。
3、IMAGE
IMAGE 数据类型用于存储大量的二进制数据Binary Data。其理论容量为2的31次方-1(2,147,483,647)个字节。其存储数据的模式与TEXT 数据类型相同。通常用来存储图形等OLE Object Linking and Embedding,对象连接和嵌入)对象。在输入数据时同BINARY数据类型一样,必须在数据前加上字符“0X”作为二进制标识。
以上就是关于MySQL里存储图片的是什么数据类型全部的内容,包括:MySQL里存储图片的是什么数据类型、数据库存储图片用什么类型、数据库中用什么数据类型存储电话号码比较合理等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)