MySQL 数据库简介+Vs2010链接数据库

 一、MySQL数据类型

1、整型

MySQL数据类型 含义(有符号)
tinyint(m) 1个字节  范围(-128~127)
smallint(m) 2个字节  范围(-32768~32767)
mediumint(m) 3个字节  范围(-8388608~8388607)
int(m) 4个字节  范围(-2147483648~2147483647)
bigint(m) 8个字节  范围(+-9.22*10的18次方)

取值范围如果加了unsigned,则最大值翻倍,如tinyint unsigned的取值范围为(0~256)。 
int(m)里的m是表示SELECT查询结果集中的显示宽度,并不影响实际的取值范围,没有影响到显示的宽度,不知道这个m有什么用。

2、浮点型(float和double)

MySQL数据类型 含义
float(m,d) 单精度浮点型    8位精度(4字节)     m总个数,d小数位
double(m,d) 双精度浮点型    16位精度(8字节)    m总个数,d小数位

设一个字段定义为float(5,3),如果插入一个数123.45678,实际数据库里存的是123.457,但总个数还以实际为准,即6位。

3、定点数

浮点型在数据库中存放的是近似值,而定点类型在数据库中存放的是精确值。 
decimal(m,d) 参数m<65 是总个数,d<30且 d

4、字符串(char,varchar,_text)

MySQL数据类型 含义
char(n) 固定长度,最多255个字符
varchar(n) 固定长度,最多65535个字符
tinytext 可变长度,最多255个字符
text 可变长度,最多65535个字符
mediumtext 可变长度,最多2的24次方-1个字符
longtext 可变长度,最多2的32次方-1个字符

char和varchar:
1.char(n) 若存入字符数小于n,则以空格补于其后,查询之时再将空格去掉。所以char类型存储的字符串末尾不能有空格,varchar不限于此。 
2.char(n) 固定长度,char(4)不管是存入几个字符,都将占用4个字节,varchar是存入的实际字符数+1个字节(n<=255)或2个字节(n>255),所以varchar(4),存入3个字符将占用4个字节。 
3.char类型的字符串检索速度要比varchar类型的快。

varchar和text: 
1.varchar可指定n,text不能指定,内部存储varchar是存入的实际字符数+1个字节(n<=255)或2个字节(n>255),text是实际字符数+2个字节。 
2.text类型不能有默认值。 
3.varchar可直接创建索引,text创建索引要指定前多少个字符。varchar查询速度快于text,在都创建索引的情况下,text的索引似乎不起作用。

5.二进制数据(_Blob)

1._BLOB和_text存储方式不同,_TEXT以文本方式存储,英文存储区分大小写,而_Blob是以二进制方式存储,不分大小写。 
2._BLOB存储的数据只能整体读出。 
3._TEXT可以指定字符集,_BLO不用指定字符集。

6.日期时间类型

MySQL数据类型 含义
date 日期 '2008-12-2'
time 时间 '12:25:36'
datetime 日期时间 '2008-12-2 22:06:44'
timestamp 自动存储记录修改时间

若定义一个字段为timestamp,这个字段里的时间数据会随其他字段修改的时候自动刷新,所以这个数据类型的字段可以存放这条记录最后被修改的时间。

数据类型的属性

 

MySQL关键字 含义
NULL 数据列可包含NULL值
NOT NULL 数据列不允许包含NULL值
DEFAULT 默认值
PRIMARY KEY 主键
AUTO_INCREMENT 自动递增,适用于整数类型
UNSIGNED 无符号
CHARACTER SET name 指定一个字符集

7、空间扩展字段

MySQL支持空间扩展,允许生成、保存和分析地理特征。这些特征可用于MyISAM、InnoDB、NDB、BDB和ARCHIVE表。MySQL实施了OGC建议的具有Geometry类型的SQL环境的一个子集。MySQL定义了一下几个几何类型:

Geometry类:Geometry是层次结构的根类,是一种非实例化类,但具有很多属性,这些属性对由Geometry子类创建的所有几何值来说是共同的。

Point类:Point点指的是代表坐标空间中单个位置的几何类。

Curve类:Curve曲线是一种1维几何对象,通常表示一系列点,是一种非实例化类。

LineString类:LineString是具有点之间线性内插特性的Curve。

Surface类:Surface是一种2维几何对象,一种非实例化类。

Polygon类:Polygon是代表多边几何对象的平面Surface。它由单个外部边界以及0或多个内部边界定义,其中,每个内部边界定义为Polygon中的一个孔。

GeometryCollection类:GeometryCollection是由一个或多个任意类几何对象构成的几何对象,其中的所有元素必须具有相同的空间参考系。

MultiPoint类:MultiPoint是一种由Point元素构成的几何对象集合。这些点未以任何方式连接或排序。

MultiCurve类:MultiCurve是一种由Curve元素构成的几何对象集合,是一种非实例化类。

MultiLineString类:MultiLineString是一种由LineStirng元素构成的MultiCurve几何对象集合。

MultiSurface类:MultiSurface是一种由Surface元素构成的几何对象,是一种非实例化类。

MultiPolygon类:MultiPolygon是一种由Polygon元素构成的几何对象集合。

支持的空间数据格式:WKT和WKB

WKT:为与采用ASCII格式的几何数据进行交换而设计的著名文本格式。POINT(15 20)、LINESTRING(0 0,10 10,20 25,50 60)、POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,5 7,7 7,7 5,5 5))、MULTIPOINT(0 0, 20 20, 60 60)、MULTILINESTRING((10 10, 20 20), (15 15, 30 15))、MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0)),((5 5,7 5,7 7,5 7, 5 5)))。

WKB:用于以二进制流的形式交换几何对象,二进制流由含几何WKB信息的BLOB值表示。

创建空间列:

create table geometry_type(id int primary key auto_increment, point point, line linestring, area polygon,pointCollection multipoint, lineCollection multilinestring,areaCollection multipolygon);

创建空间值:

insert into geometry_type (point,line,area,pointColl,lineColl,areaColl) values (PointFromText('POINT(0 0)'),LineFromText('LINESTRING(0 0,10 10,20 25,50 60)'),

PolygonFromText('POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,5 7,7 7,7 5,5 5))'),MPointFromText('MULTIPOINT(0 0, 20 20, 60 60)'),

MLineFromText('MULTILINESTRING((10 10, 20 20), (15 15, 30 15))'),MPolyFromText('MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0)),((5 5,7 5,7 7,5 7, 5 5)))'));

获取空间值:

select astext(point) from geometry_type;

select asbinary(point) from geometry_type;

分析空间信息:

MySQL提供了一组在空间数据上执行各种操作的函数。用于在各种格式间转换几何值的函数、用于访问几何值定性或定量属性的函数、描述两种几何值之间关系的

函数、从已有Geometry创建新Geometry的函数。

         ·Geometry格式转换函数:

·asBinary():将采用内部几何格式的值转换为其WKB表示,并返回二进制结果。
·asText():将采用内部几何格式的值转换为WKT表示,并返回字符串结果。
·GeomFormText():将字符串值从其WKT表示转换为内部几何格式。
·GeomFormWKB():将二进制值从其WKB表示转换为内部几何格式。
·Geometry函数:
·Dimension(g):返回几何值g的固有维数。
·Envelope(g):返回几何值g的最小边界矩形。
·GeometryType(g):以字符串形式返回几何类型的名称。
·SRID(g):返回指明几何值g的空间参考系统ID的整数。
·Point函数:
·X(g):以双精度数值返回点p的x坐标值。
·Y(g):以双精度数值返回点p的y坐标值。
·LineString函数:
·EndPoint(ls):返回LineString值ls的最后一个点。
·GLength(ls):以双精度数值返回LineString值ls在相关的空间参考系中的长度。
·NumPoints(ls):返回ls中的点数。
·PointN(ls,n):返回ls中的第n个点,编号从1开始。
·StartPoint(ls):返回ls的第一个点Point。
·Polygon函数:
·Area(poly):以双精度数值形式返回poly的面积,根据在其空间参考系中的测量值。
·ExteriorRing(poly):以LineString形式返回poly的外环。
·InteriorRingN(poly,n):以LineString形式返回poly的第n个内环,编号从1开始。
·NumInteriorRings(poly):返回poly的内环数目。
·关于几何最小边界矩形(MBR)的关系:
·MBRContains(g1,g2):指明g1的最小边界矩形是否包含g2的最小边界矩形。
·MBRDisjoint(g1,g2):指明g1和g2的最小边界矩形是否不相交。
·MBREqual(g1,g2):指明g1和g2的最小边界矩形是否相同。
·MBRIntersects(g1,g2):指明g1和g2的最小边界矩形是否相交。
·MBROverlaps(g1,g2):指明g1和g2的最小边界矩形是否交叠。
·MBRTouches(g1,g2):指明g1和g2的最小边界矩形是否接触。
·MBRWithin(g1,g1):指明g1的最小边界矩形是否位于g2的最小边界矩形内。

优化空间分析:

create table geom (g geometry not null, spatial index(g));

对于MyISAM表,spatial index负责创建R-tree索引。对于支持空间索引的其他存储引擎,spatial index能够创建B-tree索引。对于准确的值查找而不是范围扫描,作用

在空间值上的B-tree索引很有用。

二、MySQL数据库引擎简介

Innodb引擎

Innodb引擎提供了对数据库ACID事务的支持,并且实现了SQL标准的四种隔离级别,关于数据库事务与其隔离级别的内容请见数据库事务与其隔离级别这篇文章。该引擎还提供了行级锁和外键约束,它的设计目标是处理大容量数据库系统,它本身其实就是基于MySQL后台的完整数据库系统,MySQL运行时Innodb会在内存中建立缓冲池,用于缓冲数据和索引。但是该引擎不支持FULLTEXT类型的索引,而且它没有保存表的行数,当SELECT COUNT(*) FROM TABLE时需要扫描全表。当需要使用数据库事务时,该引擎当然是首选。由于锁的粒度更小,写操作不会锁定全表,所以在并发较高时,使用Innodb引擎会提升效率。但是使用行级锁也不是绝对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表。

MyIASM引擎

MyIASM是MySQL默认的引擎,但是它没有提供对数据库事务的支持,也不支持行级锁和外键,因此当INSERT(插入)或UPDATE(更新)数据时即写操作需要锁定整个表,效率便会低一些。不过和Innodb不同,MyIASM中存储了表的行数,于是SELECT COUNT(*) FROM TABLE时只需要直接读取已经保存好的值而不需要进行全表扫描。如果表的读操作远远多于写操作且不需要数据库事务的支持,那么MyIASM也是很好的选择。

两种引擎的选择

大尺寸的数据集趋向于选择InnoDB引擎,因为它支持事务处理和故障恢复。数据库的大小决定了故障恢复的时间长短,InnoDB可以利用事务日志进行数据恢复,这会比较快。主键查询在InnoDB引擎下也会相当快,不过需要注意的是如果主键太长也会导致性能问题,关于这个问题我会在下文中讲到。大批的INSERT语句(在每个INSERT语句中写入多行,批量插入)在MyISAM下会快一些,但是UPDATE语句在InnoDB下则会更快一些,尤其是在并发量大的时候。

Index——索引

索引(Index)是帮助MySQL高效获取数据的数据结构。MyIASM和Innodb都使用了树这种数据结构做为索引,关于树我也曾经写过一篇文章树是一种伟大的数据结构,只是自己的理解,有兴趣的朋友可以去阅读。下面我接着讲这两种引擎使用的索引结构,讲到这里,首先应该谈一下B-Tree和B+Tree。

B-Tree和B+Tree

B+Tree是B-Tree的变种,那么我就先讲B-Tree吧,相信大家都知道红黑树,这是我前段时间学《算法》一书时,实现的一颗红黑树,大家可以参考。其实红黑树类似2,3-查找树,这种树既有2叉结点又有3叉结点。B-Tree也与之类似,它的每个结点做多可以有d个分支(叉),d称为B-Tree的度,如下图所示,它的每个结点可以有4个元素,5个分支,于是它的度为5。B-Tree中的元素是有序的,比如图中元素7左边的指针指向的结点中的元素都小于7,而元素7和16之间的指针指向的结点中的元素都处于7和16之间,正是满足这样的关系,才能高效的查找:首先从根节点进行二分查找,找到就返回对应的值,否则就进入相应的区间结点递归的查找,直到找到对应的元素或找到null指针,找到null指针则表示查找失败。这个查找是十分高效的,其时间复杂度为O(logN)(以d为底,当d很大时,树的高度就很低),因为每次检索最多只需要检索树高h个结点。

B-Tree

接下来就该讲B+Tree了,它是B-Tree的变种,如下面两张图所示:

B+Tree
B+Tree2vcHLx/i85LLp0a/Qp8LKoaM8L3A+DQo8aDMgaWQ9"myisam引擎的索引结构">MyISAM引擎的索引结构

MyISAM引擎的索引结构为B+Tree,其中B+Tree的数据域存储的内容为实际数据的地址,也就是说它的索引和实际的数据是分开的,只不过是用索引指向了实际的数据,这种索引就是所谓的非聚集索引

Innodb引擎的索引结构

MyISAM引擎的索引结构同样也是B+Tree,但是Innodb的索引文件本身就是数据文件,即B+Tree的数据域存储的就是实际的数据,这种索引就是聚集索引。这个索引的key就是数据表的主键,因此InnoDB表数据文件本身就是主索引。

因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。

并且和MyISAM不同,InnoDB的辅助索引数据域存储的也是相应记录主键的值而不是地址,所以当以辅助索引查找时,会先根据辅助索引找到主键,再根据主键索引找到实际的数据。所以Innodb不建议使用过长的主键,否则会使辅助索引变得过大。建议使用自增的字段作为主键,这样B+Tree的每一个结点都会被顺序的填满,而不会频繁的分裂调整,会有效的提升插入数据的效率。

三、VS2010链接数据库

在VS2010的工程文件的属性信息中添加MySQL数据库的include文件夹同时在链接器中选择所需的lib文件即可。如图4所示,。MySQL 数据库简介+Vs2010链接数据库_第1张图片

MySQL 数据库简介+Vs2010链接数据库_第2张图片

图4 建立VS2010与MySQL数据库的连接

         配置完成后在包含MySQL所需的mysql.h头文件,即可实现对数据库的连接。

数据库链接代码C++:

#include   //一定要包含这个,或者winsock2.h
#include "mysql.h"    //引入mysql头文件(一种方式是在vc目录里面设置,一种是文件夹拷到工程目录,然后这样包含)
bool ConnectDatabase()
{
	//初始化mysql
	mysql_init(&mysql);  //连接mysql,数据库

	//返回false则连接失败,返回true则连接成功
	if (!(mysql_real_connect(&mysql,"localhost", "root", "shmily", "mylord",3306,NULL,0))) //中间分别是主机,用户名,密码,数据库名,端口号(可以写默认0或者3306等),可以先写成参数再传进去
	{
		printf( "Error connecting to database:%s\n",mysql_error(&mysql));
		return false;
	}
	else
	{
		printf("Connected...\n");
		return true;
	}
}
四、VS2010链接数据库实现查询与插入操作代码:
#include 
#include   //一定要包含这个,或者winsock2.h
#include "mysql.h"    //引入mysql头文件(一种方式是在vc目录里面设置,一种是文件夹拷到工程目录,然后这样包含)
#include 
#include 
#include 
#include 
#include 
#include 
//包含附加依赖项,也可以在工程--属性里面设置
//#pragma comment(lib,"wsock32.lib")
//#pragma comment(lib,"libmysql.lib")
MYSQL mysql; //mysql连接
MYSQL_FIELD *fd;  //字段列数组
char field[32][32];  //存字段名二维数组
MYSQL_RES *res; //这个结构代表返回行的一个查询结果集
MYSQL_ROW row;
MYSQL_ROW column; //一个行数据的类型安全(type-safe)的表示,表示数据行的列
char query[150]; //查询语句
bool ConnectDatabase();     //函数声明
bool QueryDatabase1();  //查询1
bool QueryDatabase2();  //查询2
bool InsertData();
bool InsertDataWithIndex();
void FreeConnect();

int _tmain(int argc, _TCHAR* argv[])
{

	ConnectDatabase();
	// InsertDataWithIndex();
	//QueryDatabase1();
	QueryDatabase2();
	system("pause");
	return 0;
}

//连接数据库
bool ConnectDatabase()
{
	//初始化mysql
	mysql_init(&mysql);  //连接mysql,数据库

	//返回false则连接失败,返回true则连接成功
	if (!(mysql_real_connect(&mysql,"localhost", "root", "shmily", "mylord",3306,NULL,0))) //中间分别是主机,用户名,密码,数据库名,端口号(可以写默认0或者3306等),可以先写成参数再传进去
	{
		printf( "Error connecting to database:%s\n",mysql_error(&mysql));
		return false;
	}
	else
	{
		printf("Connected...\n");
		return true;
	}
}
//释放资源
void FreeConnect()
{
	//释放资源
	mysql_free_result(res);
	mysql_close(&mysql);
}
//插入数据
bool InsertDataWithIndex()
{
	FILE *fpin=fopen("MX_HIWAY.MIF","r");
	if (fpin == NULL)
	{

		return false;
	}

	while ( !feof(fpin))
	{
		char s_dk[10];
		int m_count=0;
		fscanf(fpin, "%s", s_dk);
		if (strcmp(s_dk, "Pline")  ==  0 || strcmp(s_dk, "Line")  ==  0)		// 画线
		{
			if (strcmp(s_dk, "Line")  ==  0)
			{
				m_count = 2;
			}
			else fscanf(fpin, "%d", &m_count);

			std::vector> PLine(m_count);
			for (int i=0; i < m_count; i++)
			{

				fscanf(fpin, "%lf%lf",&PLine[i].first,&PLine[i].second);

			}
			int m_style=0;
			int m_width=0;
			int m_color=0;
			fscanf(fpin,"    Pen (%d,%d,%d)",&m_style,
				&m_width,&m_color);//获得画笔
			for (int i=0; i < m_count; i++)
			{
				std::stringstream ss;
				std::string SQL="";
				std::string temp="";
				SQL="insert into us_hiway_without_spatial_index values ('PLine','";
				ss<>temp;
				//SQL+=m_count;
				SQL+=temp;
				SQL+="','";
				ss.clear();
				ss<>temp;
				SQL+=temp;
				//SQL+=PLine[i].first;
				SQL+="','";
				ss.clear();
				ss<>temp;
				SQL+=temp;
				//SQL+=PLine[i].second;
				SQL+="','";
				ss.clear();
				ss<>temp;
				SQL+=temp;
				//SQL+=m_style;
				SQL+="','";
				ss.clear();
				ss<>temp;
				SQL+=temp;
				//SQL+=m_width;
				SQL+="','";
				ss.clear();
				ss<>temp;
				SQL+=temp;
				//SQL+=m_color;
				SQL+="');";
				char *p=(char *)SQL.data();
				sprintf(query,p);
				if(mysql_query(&mysql, query))        //执行SQL语句
				{
					printf("Query failed (%s)\n",mysql_error(&mysql));
					//return false;
				}
				else
				{
					printf("Insert success\n");
					//return true;
				}
			}
		} //end if

	}
	fclose(fpin);
}
bool InsertData()
{
	FILE *fpin=fopen("MX_HIWAY.MIF","r");
	if (fpin == NULL)
	{
		
		return false;
	}

	while ( !feof(fpin))
	{
		char s_dk[10];
		int m_count=0;
		fscanf(fpin, "%s", s_dk);
		if (strcmp(s_dk, "Pline")  ==  0 || strcmp(s_dk, "Line")  ==  0)		// 画线
		{
			if (strcmp(s_dk, "Line")  ==  0)
			{
				m_count = 2;
			}
			else fscanf(fpin, "%d", &m_count);
			
			std::vector> PLine(m_count);
			for (int i=0; i < m_count; i++)
			{
				
				fscanf(fpin, "%lf%lf",&PLine[i].first,&PLine[i].second);
						
			}
			int m_style=0;
			int m_width=0;
			int m_color=0;
			fscanf(fpin,"    Pen (%d,%d,%d)",&m_style,
				&m_width,&m_color);//获得画笔
			for (int i=0; i < m_count; i++)
			{
				std::stringstream ss;
				std::string SQL="";
				std::string temp="";
				SQL="insert into us_hiway values ('PLine','";
				ss<>temp;
				//SQL+=m_count;
				SQL+=temp;
				SQL+="',point(";
				ss.clear();
				ss<>temp;
				SQL+=temp;
				//SQL+=PLine[i].first;
				SQL+=",";
				ss.clear();
				ss<>temp;
				SQL+=temp;
				//SQL+=PLine[i].second;
				SQL+="),'";
				ss.clear();
				ss<>temp;
				SQL+=temp;
				//SQL+=m_style;
				SQL+="','";
				ss.clear();
				ss<>temp;
				SQL+=temp;
				//SQL+=m_width;
				SQL+="','";
				ss.clear();
				ss<>temp;
				SQL+=temp;
				//SQL+=m_color;
				SQL+="');";
				char *p=(char *)SQL.data();
				
				sprintf(query,p);
				if(mysql_query(&mysql, query))        //执行SQL语句
				{
					printf("Query failed (%s)\n",mysql_error(&mysql));
					//return false;
				}
				else
				{
					printf("Insert success\n");
					//return true;
				}
			}
		} //end if
		
	}
	fclose(fpin);
}
bool QueryDatabase1()
{
	clock_t start,finish;
	double duration;
	start=clock();
	//SET @bbox = 'POLYGON((-100 10, -90 10, -90 20, -100 20, -100 10))';
	sprintf(query, "SELECT * FROM mylord.us_hiway WHERE Intersects( location, GeomFromText(@bbox) ); "); //执行查询语句,这里是查询所有,user是表名,不用加引号,用strcpy也可以
	mysql_query(&mysql,"set names gbk"); //设置编码格式(SET NAMES GBK也行),否则cmd下中文乱码
	mysql_query(&mysql,"SET @bbox = 'POLYGON((-100 10, -90 10, -90 20, -100 20, -100 10))'; ");
	//返回0 查询成功,返回1查询失败
	if(mysql_query(&mysql, query))        //执行SQL语句
	{
		printf("Query failed (%s)\n",mysql_error(&mysql));
		return false;
	}
	else
	{
		printf("query success\n");
	}
	//获取结果集
	/*
	if (!(res=mysql_store_result(&mysql)))    //获得sql语句结束后返回的结果集
	{
		printf("Couldn't get result from %s\n", mysql_error(&mysql));
		return false;
	}

	//打印数据行数
	printf("number of dataline returned: %d\n",mysql_affected_rows(&mysql));

	//获取字段的信息
	while(row = mysql_fetch_row(res))  
     {  
        /** 
          * MYSQL_ROW STDCALL mysql_fetch_row(MYSQL_RES *result); 
           * 检索行 
         */  
  /*
        for(int t=0;t-100 and X<-90 and Y>10 and Y<20;"); //执行查询语句,这里是查询所有,user是表名,不用加引号,用strcpy也可以
	mysql_query(&mysql,"set names gbk"); //设置编码格式(SET NAMES GBK也行),否则cmd下中文乱码
	//返回0 查询成功,返回1查询失败
	if(mysql_query(&mysql, query))        //执行SQL语句
	{
		printf("Query failed (%s)\n",mysql_error(&mysql));
		return false;
	}
	else
	{
		printf("query success\n");
	}
	finish=clock();
	duration=(double)(finish-start)/CLOCKS_PER_SEC;
	printf("select without index time:\n %.6f 毫秒\n",duration*1000);	
	/*
	//获取结果集
	if (!(res=mysql_store_result(&mysql)))    //获得sql语句结束后返回的结果集
	{
		printf("Couldn't get result from %s\n", mysql_error(&mysql));
		return false;
	}

	//打印数据行数
	printf("number of dataline returned: %d\n",mysql_affected_rows(&mysql));

	//获取字段的信息
	while(row = mysql_fetch_row(res))  
     {  
        /** 
          * MYSQL_ROW STDCALL mysql_fetch_row(MYSQL_RES *result); 
           * 检索行 
         */  
  /*
        for(int t=0;t



你可能感兴趣的:(MySQL数据库)