达梦数据库数据类型、表类型和索引介绍

参考文档:DM 逻辑结构概述 | 达梦技术文档

数据类型

1、字符数据类型

系统参数:UNICODE_FLAG,0 代表 gb18030;1 代表 UTF-8。

配置 字段长度 英文存储个数 中文存储个数 实际字节数 备注

GB18030, LENGTH_IN_CHAR=0 VARCHAR(10) 10 5 10 中文占 2 字节

GB18030, LENGTH_IN_CHAR=1 VARCHAR(10) 20 10 20 中文站 2 字节,以字符为单位,自动扩充为双倍字节数

UTF-8, LENGTH_IN_CHAR=0 VARCHAR(10) 10 3.3 10 中文占 3 字节

UTF-8, LENGTH_IN_CHAR=1 VARCHAR(10) 40 13.3 40 中文站 3 字节,以字符为单位,自动扩充为 4 倍字节数

举例:UTF-8, LENGTH_IN_CHAR=0

create table users (id int,name varchar(10));

insert into users(id,name) values (1,'哈哈哈哈');提示超出长度

insert into users(id,name) values (1,'哈哈哈');成功

查询数据库的页大小

SELECT '页大小',cast(PAGE()/1024 as varchar);

2、数值数据类型

精确数值数据类型包括:NUMERIC、DECIMAL、DEC 类型、NUMBER 类型、INTEGER 类型、INT 类型、BIGINT 类型、TINYINT 类型、BYTE 类型、SMALLINT 类型、BINARY 类型、VARBINARY 类型。

近似数值类型包括:FLOAT 类型、DOUBLE 类型、REAL 类型、DOUBLE PRECISION 类型

举例:NUMERIC(4,1) 定义了小数点前面 3 位和小数点后面 1 位,共 4 位的数字,范围在 -999.9 到 999.9。

create table users (id int,qty numeric(4,1));

insert into users(id,qty) values (1,1000); 失败

insert into users(id,qty) values (1,999); 成功

3、位串数据类型

BIT:BIT 类型用于存储整数数据 1、0 或 NULL,只有 0 才转换为假,其他非空、非 0 值都会自动转换为真,可以用来支持 ODBC 和 JDBC 的布尔数据类型。DM 的 BIT 类型与 SQL Server 2000 的 BIT 数据类型相似。

举例:

create table users (id int,sex bit);

insert into users(id,sex) values (1,0);

insert into users(id,sex) values (2,1);

4、日期数据类型

日期时间数据类型分为一般日期时间数据类型、时间间隔数据类型和时区数据类型三类,用于存储日期、时间和它们之间的间隔信息。

4.1一般日期时间数据类型

DATE:年月日;TIME:时分秒;TIMESTAMP:年月日时分秒

举例:

CREATE TABLE users(

id INT,

        pay_date DATE,

        pay_time TIME(2),

        pay_timestamp TIMESTAMP

);

INSERT INTO users values(1,'2020-11-19','23:59:59','2020-11-19 23:59:59');

注意:time和timestamp秒字段后面位数取值范围为0-6,默认为0

4.2时间间隔数据类型

年-月间隔类和日-时间隔类;前者结合年月,后者结合日时分秒;默认精度为6

类型名

类型描述

INTERVAL YEAR(P)

年间隔,即两个日期之间的年数字,P 为时间间隔的引导精度

INTERVAL MONTH(P)

月间隔,即两个日期之间的月数字,P 为时间间隔的引导精度

INTERVAL DAY(P)

日间隔,即为两个日期/时间之间的日数字,P 为时间间隔的引导精度

INTERVAL HOUR(P)

时间隔,即为两个日期/时间之间的时数字,P 为时间间隔的引导精度

INTERVAL MINUTE(P)

分间隔,即为两个日期/时间之间的分数字,P 为时间间隔的引导精度

INTERVAL SECOND(P,Q)

秒间隔,即为两个日期/时间之间的秒数字,P 为时间间隔的引导精度,Q 为时间间隔秒精度

INTERVAL YEAR(P) TO MONTH

年月间隔,即两个日期之间的年月数字,P 为时间间隔的引导精度

INTERVAL DAY(P) TO HOUR

日时间隔,即为两个日期/时间之间的日时数字,P 为时间间隔的引导精度

INTERVAL DAY(P) TO MINUTE

日时分间隔,即为两个日期/时间之间的日时分数字,P 为时间间隔的引导精度

INTERVAL DAY(P)TO SECOND(Q)

日时分秒间隔,即为两个日期/时间之间的日时分秒数字,P 为时间间隔的引导精度,Q 为时间间隔秒精度

INTERVALL HOUR(P) TO MINUTE

时分间隔,即为两个日期/时间之间的时分数字,P 为时间间隔的引导精度

INTERVAL HOUR(P) TO SECOND(Q)

时分秒间隔,即为两个日期/时间之间的时分秒数字,P 为时间间隔的引导精度,Q 为时间间隔秒精度

INTERVAL MINUTE(P) TO SECOND(Q)

分秒间隔,即为两个日期/时间之间的分秒间隔,P 为时间间隔的引导精度,Q 为时间间隔秒精度

5、多媒体数据类型

TEXT/LONG/LONGVARCHAR 类型:变长字符串类型。其字符串的长度最大为 100G-1,用于存储长的文本串。

IMAGE/LONGVARBINARY 类型:用于指明多媒体信息中的图像类型,长度最大为 100G-1 字节。

BLOB 类型:用于指明变长的二进制大对象,长度最大为 100G-1 字节。

CLOB 类型:用于指明变长的字母数字字符串,长度最大为 100G-1 字节。

BFILE 类型:用于指明存储在操作系统中的二进制文件。

举例:

CREATE TABLE users(

        c1 TEXT,

        c2 BLOB,

        c3 CLOB,

        c4 IMAGE

);

INSERT INTO users values('dameng','0x123456789','clob','0x987654321');

表类型

1、普通表

2、临时表

DM 临时表支持以下功能:

  1. 在临时表中,会话可以像普通永久表一样更新、插入和删除数据;
  2. 临时表的 DML 操作产生较少的 REDO 日志;
  3. 临时表支持建索引,以提高查询性能;
  4. 在一个会话或事务结束后,数据将自动从临时表中删除;
  5. 不同用户可以访问相同的临时表,每个用户只能看到自己的数据;
  6. 临时表的数据量很少,意味着更高效的查询效率;
  7. 临时表的表结构在数据删除后仍然存在,便于以后的使用;
  8. 临时表的权限管理跟普通表一致。

事务级和会话级

ON COMMIT DELETE ROWS:指定临时表是事务级的,每次事务提交或回滚之后,表中所有数据都被删除;

ON COMMIT PRESERVE ROWS:指定临时表是会话级的,会话结束时才清空表,并释放临时 B 树。

举例 创建一个事务级的临时表

Copy  CREATE GLOBAL TEMPORARY TABLE TMP_EMP(

    EMPNO INT PRIMARY KEY,

    ENAME VARCHAR(15)   NOT NULL,

    JOB VARCHAR(10))

  ON COMMIT DELETE ROWS;

3、分区表

概念:分区是指将表、索引等数据库对象划分为较小的可管理片段的技术,每一个片段称为分区子表或分区索引。一个表被分区后,对表的查询操作可以局限于某个分区进行,而不是整个表,这样可以大大提高查询速度。

在创建表的语法中,使用 partition 子句指定分区方式和分区列,以及分区的名字等信息,即可创建分区表。而分区子表可以指定 storage 子句,设置子表的存储属性,如所属表空间等;如果不指定,则继承分区主表的存储特性及表的其他属性。同时,支持多级分区表。

查看创建表sql:CALL SP_TABLEDEF('SYSDBA', 'users');

3.1范围分区表

CREATE  TABLE  users(

    id int,

time DATETIME    

)

    PARTITION BY RANGE(time)(

    PARTITION p1 VALUES LESS THAN ('2025-04-01'),

    PARTITION p2 VALUES LESS THAN ('2025-07-01'),

    PARTITION p3 VALUES LESS THAN ('2025-10-01'),

    PARTITION p4 VALUES EQU OR LESS THAN ('2025-12-31')  //'2025-12-31'也可替换为MAXVALUE

);

INSERT INTO users values(1,'2025-03-01'),(2,'2025-05-01');

SELECT * FROM users PARTITION (p1); 查询分区p1

3.2LIST分区表

对于字符型数据,取值比较固定的,则适合于采用 LIST 分区的方法。

CREATE TABLE  users(

id INT,

city CHAR(20)

)

PARTITION BY LIST(city)(

PARTITION p1 VALUES ('北京', '天津'),

PARTITION p2 VALUES ('广州', '深圳')

);

INSERT INTO users values(1,'北京'),(2,'广州');

SELECT * FROM users PARTITION (p1);

3.3哈希分区表

CREATE  TABLE  users(

id INT,

city CHAR(20)

)

PARTITION BY HASH(city)(

PARTITION p1,

PARTITION p2

);

INSERT INTO users values(1,'北京'),(2,'广州');

SELECT * FROM users PARTITION (p1);

注意:哈希分区表分区名是匿名的,DM 统一使用 DMHASHPART+ 分区号(从 0 开始)作为分区名。

3.4创建多级分区表

CREATE  TABLE  users(

    SALES_ID  INT,

    SALEDATE DATETIME,

    CITY   CHAR(10)

    )

    PARTITION BY LIST(CITY)

     SUBPARTITION BY RANGE(SALEDATE) SUBPARTITION TEMPLATE(

        SUBPARTITION P11 VALUES LESS THAN ('2012-04-01'),

        SUBPARTITION P12 VALUES LESS THAN ('2012-07-01'),

        SUBPARTITION P13 VALUES LESS THAN ('2012-10-01'),

        SUBPARTITION P14 VALUES EQU OR LESS THAN (MAXVALUE))

    (

        PARTITION P1 VALUES ('北京', '天津')

        (

          SUBPARTITION P11_1 VALUES LESS THAN ('2012-10-01'),

          SUBPARTITION P11_2 VALUES EQU OR LESS THAN (MAXVALUE)

        ),

        PARTITION P2 VALUES ('上海', '南京', '杭州'),

        PARTITION P3 VALUES (DEFAULT)

    );

INSERT INTO users values(1,'2012-04-01','北京'),(2,'2012-04-01','上海'),(3,'2012-04-01','武汉');

SELECT * FROM users PARTITION (P1);

SELECT * FROM users SUBPARTITION (P11_2);

SELECT * FROM users SUBPARTITION (P3_P12);

4.列存储表(HUGE)

列存储:表的数据存储方式分为行存储和列存储。行存储是以记录为单位进行存储的,数据页面中存储的是完整的若干条记录;列存储是以列为单位进行存储的,每一个列的所有行数据都存储在一起,而且一个指定的页面中存储的都是某一个列的连续数据。

HUGE 表的存储方式有以下几个优点:

  1. 同一个列的数据都是连续存储的,可以加快某一个列的数据查询速度;
  2. 连续存储的列数据,具有更大的压缩单元和数据相似性,可以获得远优于行存储的压缩效率,压缩的单位是区;
  3. 条件扫描借助数据区的统计信息进行精确过滤,可以进一步减少 IO,提高扫描效率;
  4. 允许建立二级索引;
  5. 支持以 ALTER TABLE 的方式添加或者删除 PK 和 UNIQUE 约束。

4.1非事务型HUGE表

对非事务型 HUGE 表的增、删、改是直接对 HUGE 表进行写操作的,不写 UNDO 日志,不通过 BUFFER 缓存,直接操纵文件,速度快,但也因此导致不支持事务。另外,非事务型 HUGE 表中的 ROWID 是不固定的。

AUX辅助表:对于每个 HUGE 表,相应地配备一个 AUX 辅助表来管理其数据,AUX 辅助表是在创建 HUGE 表时系统自动创建的,表名为“表名$AUX”,如果该 HUGE 表为分区表,则辅助表名为“子表名$AUX”。

  1. COLID:表示当前这条记录对应的区所在的列的列 ID 号;
  2. SEC_ID:表示当前这个记录对应的区的区 ID 号,每一个区都有一个 ID 号,并且唯一;
  3. FILE_ID:表示这个区的数据所在的文件号;
  4. OFFSET:表示这个区的数据在文件中的偏移位置,4K 对齐;
  5. COUNT:表示这个区中存储的数据总数(有可能包括被删除的数据);
  6. ACOUNT:表示这个区中存储的实际数据行数;
  7. N_LEN:表示这个区中存储的数据在文件中的长度,4K 对齐的;
  8. N_NULL:表示这个区中的数据中包括的 NULL 值的行数;
  9. N_DIST:保留字段,无意义;
  10. CPR_FLAG:表示这个区是否压缩;
  11. ENC_FLAG:表示这个区是否加密;
  12. CHKSUM:用来存储标记位;
  13. MAX_VAL:表示这个区中的最大值,精确值;
  14. MIN_VAL:表示这个区中的最小值,精确值;
  15. SUM_VAL:表示这个区中所有值的和,精确值。

  CREATE HUGE TABLE T1(A INT, B INT) STORAGE(WITHOUT DELTA);

4.2事务型HUGE表

通过增加 RAUX、DAUX 和 UAUX 行辅助表,减少了事务型 HUGE 表增、删、改操作的 IO,提高效率,同时提高并行性能。事务型 HUGE 表支持 UNDO 日志,实现了事务特性。

1、RAUX 行辅助表(插入):RAUX 行辅助表中内容对应于 HUGE 表中的最后一部分记录(不够存满一个数据区的)。当 RAUX 表中数据达到区大小时,将 RAUX 表中数据以列为单位写入各列对应的文件中,并清空 RAUX 表。RAUX 表与 HUGE 表结构相同,不论数据在哪个表中,每一行数据的 ROWID 固定不变。

2、DAUX 行辅助表(删除):DAUX 行辅助表中的一行数据对应 HUGE 表中一条或一段连续的被删除的数据,记录了被删除数据的起始行号和被删除数据的行数。删除 HUGE 表数据时,向 DAUX 行辅助表中插入对应删除数据的记录。

3、UAUX 行辅助表(更新):UAUX 行辅助表中一条记录对应 HUGE 表中更新列的一个值,记录了更新的列号、行号和更新后的值的二进制格式。更新 HUGE 表数据时,操作转换为对 UAUX 表的插入操作或更新操作。

CREATE HUGE TABLE T2 (A INT, B INT) STORAGE(WITH DELTA);

5、堆表

普通表都是以 B 树形式存放的,ROWID 都是逻辑的 ROWID,即从 1 一直增长下去。在并发情况下,每次插入过程中都需要逻辑生成 ROWID,这样影响了插入数据的效率;对于每一条数据都需要存储 ROWID 值,也会花费较大的存储空间。堆表是指采用了物理 ROWID 形式的表,即使用文件号、页号和页内偏移而得到 ROWID 值,这样就不需要存储 ROWID 值,可以节省空间。逻辑 ROWID 在插入或修改过程中,为了确保 ROWID 的唯一性,需要依次累加而得到值,这样就影响了效率,而堆表只需根据自己的文件号、页号和页内偏移就可以得到 ROWID,提高了效率。

普通表都是以 B 树形式存储在物理磁盘上,而堆表则采用一种“扁平 B 树”方式存储。

创建表方式

1、dm.ini   LIST_TABLE 

1)如果 LIST_TABLE = 1,则在未显式指定表是否为堆表或非堆表时,默认情况下创建的表为堆表;
2)如果 LIST_TABLE = 0,则在未显式指定表是否为堆表或非堆表时,默认情况下创建的表为普通表形式

2、SQL 语句显式指定

1)NOBRANCH:如果指定为 NOBRANCH,则创建的表为堆表,并发分支个数为 0,非并发分支个数为 1;
2)BRANCH(N,M):如果为该形式,则创建的表为堆表,并发分支个数为 N,非并发个数为 M;
3)BRANCH N:指定创建的表为堆表,并发分支个数为 N,非并发分支个数为 1;
4)CLUSTERBTR:创建的表为非堆表,即普通 B 树表。

举例:创建 LIST_TABLE 表有并发分支 2 个,非并发分支 4 个

CREATE TABLE LIST_TABLE(C1 INT) STORAGE(BRANCH (2,4));

索引

1、聚集索引和非聚集索引

 聚集索引(又称为一级索引、主索引):聚集索引就是按照聚集索引键构造一棵 B+ 树,表数据存储在 B+ 树叶子节点上,通过定位索引可直接在 B+ 树中找到数据。每一个表有且只有一个聚集索引。

  非聚集索引(又称为二级索引、辅助索引):将二级索引列和聚集索引列共同存储在 B+ 树叶子节点上。如果查找非聚集索引键值或聚集索引键值可直接在 B+ 树中找到;如果查找索引键值以外的数据,则需要回到一级索引中进行查找。每一个表可以有多个非聚集索引。

2、功能索引

 唯一索引:索引数据根据索引键唯一;

 函数索引:包含函数/表达式的预先计算的值;

 位图索引:对低基数的列创建位图索引;

 位图连接索引:针对两个或者多个表连接的位图索引,主要用于数据仓库中;

 全文索引:在表的文本列上而建的索引;

 空间索引:在空间数据上创建的索引,专用于 DMGEO 包中;

 数组索引:在一个只包含单个数组成员的对象列上创建的索引;

 普通索引:除了唯一索引、函数索引、位图索引、位图连接索引、全文索引、空间索引、数组索引以外的索引,均为普通索引。

3、虚索引和实索引

虚索引:指不存储数据的索引。虚索引由系统自动并隐式地创建,目的是保证约束的正确性。

举例:

CREATE TABLE T1 (C1 INT ,C2 INT UNIQUE);

CREATE TABLE T2(C1 INT,C2 INT REFERENCES T1(C2));

//查看约束对应的索引ID(INDEXID),假设为33555600

SELECT INDEXID FROM SYSCONS WHERE TABLEID=(SELECT ID FROM SYSOBJECTS WHERE NAME = 'T2');

行号       INDEXID

---------- -----------

1          33555600

//查看该索引是否为虚索引。3表示1+2。其中2代表虚索引。

SELECT FLAG FROM SYSINDEXES WHERE ID= 33555600;

行号       FLAG

---------- -----------

1          3

实索引:指存储数据的索引。虚索引以外的索引均为实索引。

4、单列索引和复合索引

单列索引:只有一个索引键的索引。

复合索引:含有多个索引键的索引。(联合索引)

5、全局索引和局部索引

全局索引:全局索引是以整张表的数据为对象而建立的索引。

全局非分区索引

//创建表

drop table t1;

create table t1(c1 int, c2 int, c3 int)  partition by range(c1)

(

partition p1 values less than(100),

partition p2 values less than(200),

partition p3 values less than(maxvalue)

);

//创建全局非分区索引

create index idx1 on t1(c2) global;

//在WHERE中指定索引列,可使用索引idx1查询

explain select * from t1 where c2 = 130;

1   #NSET2: [1, 1, 24]

2     #PRJT2: [1, 1, 24]; exp_num(4), is_atom(FALSE)

3       #PARALLEL: [1, 1, 24]; scan_type(FULL), key_num(0, 0, 0), simple(0),range_sfun_opt(0)

4         #BLKUP2: [1, 1, 24]; IDX1(T1)

5           #SSEK2: [1, 1, 24]; scan_type(ASC), IDX1(T1), scan_range[130,130],is_global(1)

//直接对分区子表查询,则使用全局本地索引

explain select * from t1_p1 where c2 = 130;

1   #NSET2: [1, 1, 24]

2     #PRJT2: [1, 1, 24]; exp_num(4), is_atom(FALSE)

3       #BLKUP2: [1, 1, 24]; INDEX3505_3504(T1_P1)

4         #SSEK2: [1, 1, 24]; scan_type(ASC), INDEX3505_3504(T1_P1), scan_range[130,130],is_global(1)

全局分区索引(DMDPC

//创建表空间

create tablespace ts1 datafile 'opt/ts/ts01.dbf' size 128 storage (on raft_1);

create tablespace ts2 datafile 'opt/ts/ts02.dbf' size 128 storage (on raft_2);

//创建表

drop table t1;

create table t1(c1 int, c2 int, c3 int)  partition by range(c1)

(

partition p1 values less than(100),

partition p2 values less than(200),

partition p3 values less than(maxvalue)

);

//创建全局分区索引

drop index idx1;

create index idx1 on t1(c2) global partition by range(c2)

(

  partition p1 values less than(1000) storage(on ts2) ,

  partition p2 values less than(maxvalue) storage(on ts1)

);

//使用索引idx1查询

explain select * from t1 where c2 = 130;  //当数据量很大时

explain select * from t1 index idx1 where c2 = 130;  //或直接指定全局索引

1   #NSET2: [2, 1, 24]

2     #ERECV: [2, 1, 24]; stask_no(-1), l_stask_no(1), n_key(0), in_turn(0), trig(0)

3       #ESEND: [2, 1, 24]; stask_no(1), type(DIRECT), sites(2:1,1:1), sql_invoke(0), pwj_opt(0), table(-); INFO_BITS(0x8)

4         #PRJT2: [2, 1, 24]; exp_num(4), is_atom(FALSE)

5           #PARALLEL: [2, 1, 24]; scan_type(FULL), key_num(0, 0, 0), simple(0), range_sfun_opt(0)

6             #BLKUP2: [2, 1, 24]; IDX1(T1)

7               #ERECV: [2, 1, 24]; stask_no(1), l_stask_no(0), n_key(0), in_turn(0), trig(0)

8                 #ESEND: [2, 1, 24]; stask_no(0), type(ROWID), sites(2:1,1:1), sql_invoke(0), pwj_opt(0), table(T1) empty_type(ERROR); INFO_BITS(0xc)

9                   #GI: [2, 1, 24]; policy(RANDOM), gi_unit[0..0], scan_type[0](FULL)

10                    #SSEK2: [2, 1, 24]; scan_type(ASC), IDX1(T1), scan_range[130,130],is_global(1)

//直接对分区子表查询,则使用全局本地索引

explain select * from t1_p1 where c2 = 130;

1   #NSET2: [1, 1, 24]

2     #PRJT2: [1, 1, 24]; exp_num(4), is_atom(FALSE)

3       #BLKUP2: [1, 1, 24]; INDEX3505_3504(T1_P1)

4         #SSEK2: [1, 1, 24]; scan_type(ASC), INDEX3505_3504(T1_P1), scan_range[130,130],is_global(1)引

局部索引

//创建表

drop table t1;

create table t1(c1 int, c2 int, c3 int)  partition by range(c1)

(

partition p1 values less than(100),

partition p2 values less than(200),

partition p3 values less than(maxvalue)

);

//创建局部索引,必须缺省GLOBAL关键字

create index idx1 on t1(c2);

//在WHERE中指定索引列,可使用索引idx1查询

explain select * from t1 where c2 = 130;

1   #NSET2: [1, 1, 24]

2     #PRJT2: [1, 1, 24]; exp_num(4), is_atom(FALSE)

3       #PARALLEL: [1, 1, 24]; scan_type(FULL), key_num(0, 0, 0), simple(0), range_sfun_opt(0)

4         #BLKUP2: [1, 1, 24]; IDX1(T1)

5           #SSEK2: [1, 1, 24]; scan_type(ASC), IDX1(T1), scan_range[130,130],is_global(0)

//直接对分区子表查询,则使用子表局部索引

explain select * from t1_p1 where c2 = 130;

1   #NSET2: [1, 1, 24]

2     #PRJT2: [1, 1, 24]; exp_num(4), is_atom(FALSE)

3       #BLKUP2: [1, 1, 24]; INDEX3505_3504(T1_P1)

4         #SSEK2: [1, 1, 24]; scan_type(ASC), INDEX3505_3504(T1_P1), scan_range[130,130],is_global(0)

达梦社区地址:达梦数据库 - 新一代大型通用关系型数据库 | 达梦在线服务平台 

<think>我们正在比较MySQL中的POINT数据类型达梦数据库中的相应数据类型。根据引用[1][2],我们知道达梦数据库MySQL在处理空间函数上存在差异,但具体到POINT数据类型,我们需要查看两者的定义用法。 在MySQL中,POINT是空间数据类型的一种,用于示一个点(通常由经纬度坐标组成)。在达梦数据库中,也有对应的空间数据类型。 根据引用[3](Mysql到DM的数据类型映射)引用[4](达梦数据库使用),我们可以尝试找出达梦数据库中与MySQL的POINT对应的类型。 然而,引用中并没有直接给出POINT类型的映射。因此,我们需要根据两种数据库的空间数据类型体系来推断。 在MySQL中,空间数据类型包括: - GEOMETRY - POINT - LINESTRING - POLYGON - 等等。 达梦数据库(以DM8为例)也支持空间数据类型,根据其文档(引用[2]中提及),达梦数据库支持的空间数据类型包括: - ST_GEOMETRY(所有空间类型的基类) - ST_POINT - ST_LINESTRING - ST_POLYGON - 等等。 因此,MySQL中的POINT类型达梦数据库中对应的应该是ST_POINT。 但是,需要注意的是,在达梦数据库中,ST_POINT是ST_GEOMETRY的子类,用于示点。同样,在MySQL中,POINT也是几何类型的一种。 在具体使用上,两者都遵循OGC(开放地理空间联盟)的标准,但函数名称用法可能有所不同(如引用[2]中提到的空间查询的差异)。 例如,在MySQL中创建一个包含POINT类型: ```sql CREATE TABLE test_points ( id INT AUTO_INCREMENT PRIMARY KEY, location POINT NOT NULL, SPATIAL INDEX(location) ); ``` 而在达梦数据库中,类似的可能这样创建: ```sql CREATE TABLE test_points ( id INT IDENTITY(1,1) PRIMARY KEY, location ST_POINT NOT NULL ); -- 注意:达梦数据库中的空间索引创建方式可能不同,需要参考达梦文档。 ``` 另外,在插入数据时,MySQL中使用ST_GeomFromText函数: ```sql INSERT INTO test_points (location) VALUES (ST_GeomFromText('POINT(10 20)')); ``` 在达梦数据库中,根据引用[2]中的示例(虽然引用[2]中讨论的是根据经纬度查询,但我们可以推断),可能使用ST_GeomFromText或者类似的函数,但函数名可能不同。实际上,达梦数据库也支持ST_GeomFromText函数(遵循OGC标准),所以插入数据的方式类似: ```sql INSERT INTO test_points (location) VALUES (ST_GeomFromText('POINT(10 20)')); ``` 但是,达梦数据库可能还支持其他方式,例如使用专门的构造函数。因此,具体使用时需要参考达梦数据库的官方文档。 总结: - MySQL中的POINT类型对应达梦数据库中的ST_POINT类型。 - 两者在创建、插入数据的基本操作上相似,但函数名称索引创建方式可能存在差异。 - 在进行空间查询(如计算距离、包含关系等)时,函数名称用法可能存在差异(如引用[2]中所述)。 因此,在迁移使用POINT数据类型时,除了数据类型映射外,还需要注意相关空间函数的转换。 §§相关问题§§ 1. 如何在达梦数据库中创建空间索引? 2. MySQL达梦数据库在处理空间查询时的主要函数差异有哪些? 3. 达梦数据库中ST_POINT类型支持哪些空间操作?</think>### MySQL POINT 数据类型达梦数据库空间数据类型对比 #### 1. **核心数据类型对比** | 特性 | MySQL | 达梦数据库 (DM) | |--------------------|--------------------------------------|----------------------------------| | **基础类型** | `POINT` | `ST_POINT` | | **空间基类** | `GEOMETRY` | `ST_GEOMETRY` | | **坐标维度** | 支持 2D/3D (需启用 `GIS` 扩展) | 原生支持 2D/3D | | **存储格式** | WKB (Well-Known Binary) | 自定义二进制格式 | | **标准遵循** | OGC SFA 标准 | OGC SFA + ISO SQL/MM 标准 | #### 2. **函数操作差异** | 操作类型 | MySQL 示例 | 达梦数据库示例 | |--------------------|--------------------------------------|----------------------------------| | **创建点** | `ST_PointFromText('POINT(10 20)')` | `ST_Point(10, 20)` | | **距离计算** | `ST_Distance(point1, point2)` | `ST_Distance(point1, point2)` | | **包含判断** | `ST_Contains(polygon, point)` | `ST_Contains(polygon, point)` | | **坐标获取** | `ST_X(point)`, `ST_Y(point)` | `point.ST_X()`, `point.ST_Y()` | > **关键差异**:达梦使用面向对象语法(如 `point.ST_X()`),而 MySQL 采用传统函数调用[^2]。 #### 3. **空间索引实现** | 特性 | MySQL | 达梦数据库 | |--------------------|--------------------------------------|----------------------------------| | **索引类型** | R-Tree (仅 MyISAM/InnoDB 支持) | R-Tree (所有引擎) | | **创建语法** | ```spatial INDEX idx_name (column)``` | ```CREATE SPATIAL INDEX idx_name ON table(column)``` | | **查询优化** | 需显式使用 `MBRContains()` 加速 | 自动优化空间谓词 | #### 4. **数据类型映射建议** 迁移 MySQL 空间数据到达梦时需注意: ```sql -- MySQL 定义 CREATE TABLE locations ( id INT PRIMARY KEY, pos POINT SRID 4326 ); -- 等效达梦定义 CREATE TABLE locations ( id INT PRIMARY KEY, pos ST_POINT SRID 4326 -- 使用 ST_POINT 替代 POINT ); ``` #### 5. **典型差异场景** **场景:查询 5km 范围内的点** ```sql -- MySQL (需使用 MBR 优化) SELECT * FROM points WHERE ST_Distance_Sphere(pos, ST_Point(116.4, 39.9)) <= 5000; -- 达梦 (直接使用空间函数) SELECT * FROM points WHERE pos.ST_Distance(ST_Point(116.4, 39.9)) <= 5000; ``` > **注意**:达梦的 `ST_Distance()` 默认返回平面距离,需用 `ST_Transform()` 转换坐标系[^2]。 --- ### 总结建议 1. **类型映射**:MySQL `POINT` → 达梦 `ST_POINT` 2. **函数迁移**:将 MySQL 的 `ST_*()` 函数改为达梦的对象方法调用 3. **索引优化**:达梦的空间索引无需特殊语法优化,但需注意坐标系一致性 4. **精度处理**:达梦默认使用双精度计算,比 MySQL 的浮点精度更高 > 迁移时建议使用达梦 DTS 工具的 **空间数据类型映射功能** 自动转换结构[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值