php 操作 MySQL 中的Blob类型
我们需要保存一个文件或者一张图片或者其他二进制或多媒体文件时,经常选择使用Blob类型!
一 基本使用
Blob就是一种Mysql的数据类型,它是一个二进制大型对象,可以作为大量数据的容器;其实更准确地说Blob是一系列数据类型:
MySQL的四种BLOB类型
类型 | 大小(单位:字节) |
TinyBlob | 最大 255 |
Blob | 最大 65K |
MediumBlob | 最大 16M |
LongBlob | 最大 4G |
这四种类型除了允许的最大值不同外,没有其他区别;实际使用中根据需要存入的数据大小定义不同的BLOB类型。
注意:如果你存储的文件过大,数据库的性能会下降很多。
图片的插入:
- <?php
- if($Picture != "none") {
- $PSize = filesize($Picture);
- $mysqlPicture = addslashes(fread(fopen($Picture, "r"), $PSize));
- mysql_connect($host,$username,$password) or die("Unable to connect to SQL server");
- @mysql_select_db($db) or die("Unable to select database");
- mysql_query("INSERT INTO Images (Image) VALUES ($mysqlPicture)") or die("Cant Perform Query");
- }else {
- echo"You did not upload any picture";
- }
- ?>
图片的读取:
在知道了如何将图插入数据库之后,我们就需要考虑怎样才能从数据库中取出图片并在HTML页面中显示出来。这个过程要稍微复杂一些,下面我们就来介绍一下实现过程。
因为PHP显示图片需要发送相应的标头,所以我们就会面临这样一个问题,那就是一次只能显示一副图片,因为我们无法在发出标头之后再发送其它的标头。
为了有效的解决这一问题,我们编写了两个文件。其中,第一个文件作为HTML页面的模板,定位图片的显示位置。第二个文件则被用来从数据库中实际输出 文件流,作为标签的SRC属性。
第一个文件的简单形式可以如下:
- <?php
- mysql_connect($host,$username,$password) or die("Unable to connect to SQL server");
- @mysql_select_db($db) or die("Unable to select database");
- $result=mysql_query("SELECT * FROM Images") or die("Cant Perform Query");
- While($row=mysql_fetch_object($result)) {
- echo "";
- }
- ?>
当HTML页面被浏览时,每显示一副图片就会调用一次Second.php3文件。当第二个文件被调用时会传入相应的Picture ID,我们可以借此从数据库中取回对应的图片并显示。
Second.php3文件如下:
- <?php
- $result=mysql_query("SELECT * FROM Images WHERE PicNum=$PicNum") or die("Cant perform Query");
- $row=mysql_fetch_object($result);
- Header( "Content-type: image/gif");
- echo $row->Image;
- ?>
text和blob比较
1.
blob是二进制大对象,可以容纳可变量数量的数据,其中blob分为4中类 型:TINYBLOB,BLOB,mediumblob和LongBlob,他们容纳的长度是不同的.
Text同样也分为四种类型:TINYTEXT 、TEXT 、MEDIUMTEXT 和LONGTEXT
2.
blob被视为二进制字符串,Text被视为非二进制字符串;
blob 列没有字符集,并且排序和比较基于列值字节的数值值。
TEXT 列有一个字符集,并且根据字符集的校对规则对值进行排序和比较。
在TEXT 或BLOB 列的存储或检索过程中,不存在大小写转换,当未运行在严格模式时,如果你为BLOB 或TEXT 列分配 一个超过该列类型的最大长度的值值,值被截取以保证适合。如果截掉的字符不是空格,将会产生一条警告。使用严格SQL 模式,会产生错误,并且值将被拒绝而不是截取并给出警告.在大多数方面,可以将BLOB 列视为能够足够大的VARBINARY 列。 同样,可以将TEXT 列视为VARCHAR 列。
3.
BLOB 和TEXT 在以下几个方面不同于VARBINARY 和VARCHAR.
BLOB 和TEXT 列不能有默认值.
当保存或检索BLOB 和TEXT 列的值时不删除尾部空格。( 这与VARBINARY 和VARCHAR 列相同).
对于BLOB 和TEXT 列的索引,必须指定索引前缀的长度。对于CHAR 和VARCHAR ,前缀长度是可选的.
LONG 和LONG VARCHAR 对应MEDIUMTEXT 数据类型。这是为了保证兼容性。如果TEXT 列 类型使用BINARY 属性,将为列分配列字符集的二元校对规则.
MySQL 连接程序/ODBC 将BLOB 值 定义为LONGVARBINARY ,将TEXT 值定义为LONGVARCHAR 。由 于BLOB 和TEXT值可能会非常长,使用它们时可能遇到一些约束.
BLOB 或TEXT 对象的 最大大小由其类型确定,但在客户端和服务器之间实际可以传递的最大值由可用内存数量和通信缓存区大小确定。你可以通过更改max_allowed_packet 变 量的值更改消息缓存区的大小,但必须同时修改服务器和客户端程序。例如,可以使用 mysql 和mysqldump 来 更改客户端的max_allowed_packet 值.
字段长度
列类型 需要的存储量
TINYINT 1 字节
SMALLINT 2 个字节
MEDIUMINT 3 个字节
INT 4 个字节
INTEGER 4 个字节
BIGINT 8 个字节
FLOAT(X) 4 如果 X < = 24 或 8 如果 25 < = X < = 53
FLOAT 4 个字节
DOUBLE 8 个字节
DOUBLE PRECISION 8 个字节
REAL 8 个字节
DECIMAL(M,D) M字节(D+2 , 如果M < D)
NUMERIC(M,D) M字节(D+2 , 如果M < D)
日期和时间类型
列类型 需要的存储量
DATE 3 个字节
DATETIME 8 个字节
TIMESTAMP 4 个字节
TIME 3 个字节
YEAR 1 字节
串类型
列类型 需要的存储量
CHAR(M) M字节,1 <= M <= 255
VARCHAR(M) L+1 字节, 在此L <= M和1 <= M <= 255
TINYBLOB, TINYTEXT L+1 字节, 在此L< 2 ^ 8
BLOB, TEXT L+2 字节, 在此 L < 2 ^ 16
MEDIUMBLOB, MEDIUMTEXT L+3 字节, 在此 L < 2 ^ 24
LONGBLOB, LONGTEXT L+4 字节, 在此 L < 2 ^ 32
ENUM('value1','value2',...) 1 或 2 个字节, 取决于枚举值的数目(最大值65535)
SET('value1','value2',...) 1,2,3,4或8个字节, 取决于集合成员的数量(最多64个成员)
MyISAM表类型:
- MyISAM表(TYPE=MYISAM)是ISAM类型的一种延伸,具有很多优化和增强的特性。
- 是MySQL的默认表类型。
- MyISAM优化了压缩比例和速度,并且可以很方便的在不同的操作系统和平台之间进行移植。
- MyISAM支持大表文件(大于4G)
- 允许对BLOB和TEXT列进行索引
- 支持使用键前缀和使用完整的键搜索记录
- 表数据和表索引文件可以依存在不同的位置,甚至是不同的文件系统中。
- 即使是具有相当多的插入、更新和删除操作的表,智能防碎片逻辑也能保证其高性能的协作性。
ISAM表类型:
ISAM表(TYPE=ISAM)和MyISAM表相似,但是其没有MyISAM格式的很多增强性能,因而不能像MyISAM类型那样提供很好的优 化和执行效率。因为ISAM索引不能被压缩 ,它比在MyISAM中的相同索引战胜较少的系统资源。ISAM索引需要较多的磁盘空间 ,这对于像本站的这种小型环境很是问题。呵呵。
和MyISAM一样,ISAM表可以是固定长度的,也可以是可变长度的,但是其格式的最大键长度比较小,ISAM 格式处理的表不能大于4G,而且表不能在不同的平台间移植 。另外,ISAM表容易分裂,这会降低查询 速度,对数据/索引的压缩产生限制 。
HELP表类型:
HEAP表(TYPE=HEAP)是内存中的表,它使用能够比较快速的散列索引(当运行INSERT查询时,独立评价指出HEAP表最少比 MyISAM表快30%),因此,对于临时表可以优化。经和MyISAM或ISAM表的访问规则和使用方式一样。存 储在里面的数据只在MySQL服务器的生命期内存在 ,如果MySQL服务器崩溃或者被关掉,都会使其中的数据消失不见。虽然HEAP表具有 性能方面的好处,但是由于它的临时性和一些其他功能限制,在实际中不可能经常使用。
HEAP表的大小只受到系统上可用内存的限制,MySQL是很聪明的,其具有内建保护来阻止无意识地使用所有可用内存。所以我们不用担心内存会被 HEAP表用尽。HEAP表不支持BLOB或TEXT列,不能超过max_heap_table_size变量指定的大小。
BerkeleyDB表类型:
BerkeleyDB表(TYPE=BDB)是为了满足MySQL开发者对事务安全表日益增长的需求而发展起来的。BerkeleyDB表具有很多 有趣的鹅,包括提交和回滚操作、多用户并发访问、检查点、次要索引、通过日志恢复崩溃、连续地和键控地访问数据等,这便利复杂的、基于事务的SQL有了可 行的选择。
不过BerkeleyDB表也有一些限制,让我们简单的了解一下:
- 它的移动比较困难(在创建时,表路径硬编码在表文件中)
- 不能压缩表索引,而且其表通常比MyISAM相应的表要大
- 有点鸡肋的感觉,因为现在InnoDB格式很大程度上可以取代BerkeleyDB格式
InnoDB表类型:
InnoDB表(TYPE=INNODB),是一个完全兼容ACID(事务的原子性、一致性、独立性及持久性)的、高效率的表完全支持MySQL的 事务处理并且不会btwagkyaakftntce。精细的(行级和表级)锁提高了MySQL事务处理的带走度,同时其也支持无锁定读操作(以前只在 Oracle中包含)和多版本的特性。
异步输入/输出和一系列的读缓冲将提高数据检索速度,同时可以进行文件的优化和内存的管理。需要的基础上支持自动在内存上创建散列索引来提高性能, 使用缓冲来提高可靠性和数据库操作的速度。InnoDB表的恨不能可以和MyISAM相媲美,甚至已经超过了MyISAM。
在不同的操作系统和体系结构上是完全可移植的。由于一直处于一致的状态(MySQL通过在启动时检查错误并修复错误来使它们更加健壮)。对外键、提交、回滚和前滚的操作的支持,使其成为MySQL中最完善的表格式 。
MERGE表类型:
- MERGE表(TYPE=MERGE)是通过把多个MyISAM表组合到一个单独的表来创建的一种虚拟表。
- 只有涉及到的表具有完全相同的表结构时才能对表进行组合。字段类型或者索引的任何不同都不能进行成功的结合。
- MERGE表使用组成表的索引,并且不能维持它本身的索引,在某种情况下可以提高速度。
- 允许SELECT,DELETE,UPDATE操作
- 在需要把不同表的数据放到一起提高连接的性能或者在一系列表中进行搜索时,这种表很实用。
- 处理大的MyISAM表时,我们可以通过压纹或者使用MySQL发布中包含的myisampack实用工具进行“打包”来减少这些表战胜的空间。 myisampack创建比较小的只读表,而不会在使用智能压缩时导致任何大的性能开销。