搜尋
首頁資料庫mysql教程Mysql分区管理基本操作_MySQL

初探:

很长时间没写博客了,这两天一直在学习Mysql分区,总结下:

Mysql支持水平分区,并不支持垂直分区;

水平分区:指将同一表中不同行的记录分配到不同的物理文件中;

垂直分区:指将同一表中不同列的记录分配到不同的物理文件中;

其中CSV、FEDORATED、MERGE等引擎不支持分区,MYISAM、InnoDB、NDB等引擎支持分区

目的:

将一个表或索引分解为多个更小、更可管理的部分,从逻辑上讲,只有一个表或者索引,但是物理上这个表或者索引可能由数十个物理分区组成;没个分区都是独立的对象,可以独自处理,也可以作为一个更大对象的一部分进行处理(如果分区表很大,亦可以将分区分配到不同的磁盘上去);在执行查询的时候,优化器会根据分区定义过滤哪些没有我们需要数据的分区,这样查询就无须全表扫描所有分区,只查找包含需要数据的分区即可

适用场景:

1、表非常大以至于无法全部都放到内存,或者只在表的最后部分有热点数据,其他均为历史数据
2、分区表数据更容易维护(可独立对分区进行优化、检查、修复及批量删除大数据可以采用drop分区的形式等)
3、分区表的数据可以分布在不同的物理设备上,从而高效地利用多个硬件设备
4、分区表可以避免某些特殊的瓶颈(ps: InnoDB的单个索引的互斥访问、ext3文件系统的inode锁竞争等)
5、可以备份和恢复独立的分区,非常适用于大数据集的场景

分区表限制:
  1. 单表最多支持1024个分区
  2. MySQL5.1只能对数据表的整型列进行分区,或者数据列可以通过分区函数转化成整型列;MySQL5.5的RANGE LIST类型可以直接使用列进行分区
  3. 如果分区字段中有主键或唯一索引的列,那么所有的主键列和唯一索引列都必须包含进来
  4. 分区表无法使用外键约束
  5. 分区必须使用相同的Engine
  6. 对于MyISAM分区表,不能在使用LOAD INDEX INTO CACHE操作
  7. 对于MyISAM分区表,使用时会打开更多的文件描述符(单个分区是一个独立的文件)
分区策略:
  1. 全量扫描数据,不需要任何索引:通过where条件大概定位哪个分区,必须将查询所需要扫描的分区个数限制在很小的数量
  2. 建立分区索引,分离热点:如将明显的热点数据分离到一个分区,使其尽量缓存到内存中,这样就能充分使用索引和缓存

    注意:以上策略均以查询得到过滤,丢掉额外的分区,分区本身不产生额外的代价为准则】
分区表使用过程的坑坑:
  1. NULL值会使分区过滤无效:

    分表的表达式的值可以是NULL,第一个分区为特殊分区存放NULL或者非法值

    如: PARTITION BY RANGE YEAR(order_date)进行分区,那么order_date为NULL或者非法值,记录存放在第一个分区:

    WHERE order_date BETWEEN ‘2014-01-01’ AND ‘2014-01-31’查询时会检查两个分区:

    第一个分区及1月份分区,避免第一分区数据过大时造成查询代价过高,可以使用:建立第一分区专门存放order_date为NULL和非法值记录
    PARTITION p_nulls VALUES LESS THAN(0)

    MySQL5.5以后可以才用一下语法解决问题:
    PARTITION BY RANGE COLUMNS(order_date)

2.分区列和索引列不匹配

此种情况下查询无法进行分区过滤,分区失效除非查询中包含了可以过滤分区的条件

3.RANGE类型分区随着分区数量增加会对MYSQL额外增加查询分区定义列表(符合条件行在哪个分区)的压力,尽量限制适当的分区数量;key和hash类型分区不存在此问题

4.重组分区或者类似alter语句可能会造成很大的开销

新建或者删除分区操作很快,重组分区或者类似ALTER语句操作会先创建一个临时的分区,将数据复制其中,然后在删除原分区

分区表类型:

1.RANGE分区:行数据基于属于一个给定连续区间的列值被放入分区

MySQL5.5开始支持RANGE COLUMNS的分区(引入Columns分区解决了MySQL 5.5版本之前RANGE分区和LIST分区只支持整数分区,从而导致需要额外的函数计算得到整数或者通过额外的转换表来转换为整数再分区的问题。Columns分区可以细分为RANGE Columns分区和LIST Columns分区,RANGE Columns分区和LIST Columns分区都支持整数、日期时间、字符串三大数据类型)

2.LIST分区:类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择。

MySQL5.5开始支持RANGE COLUMNS的分区
3.HASH分区:根据用户自定义的表达式的返回值来进行分区,返回值不能为负数
4.KEY分区:根据MySQLS数据库提供的哈希函数来进行分区
【注:无论创建何种类型的分区,如果表中存在主键或唯一索引时,分区列必须是唯一索引的一个组成部分】

分区相关查询:
查看当前数据库是否支持分区mysql> show variables like '%partition%';+---------------------------------------+-------+| Variable_name | Value |+---------------------------------------+-------+| have_partitioning | YES || innodb_adaptive_hash_index_partitions | 1 |+---------------------------------------+-------+2 rows in set查看创建分区表的CREATE语句mysql>show create table operation_log;查看表是否为分区表(Create_options)mysql>show table status(当前库所有表状态)mysql>show table status from lockrank like '%operation_log%';(lockrank库operation_log表状态)*************************** 1. row ***************************Table: operation_logCreate Table: CREATE TABLE `operation_log` (  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,  `cid` mediumint(7) unsigned NOT NULL,  `accountid` mediumint(8) NOT NULL DEFAULT '0' ,  `flag` tinyint(1) unsigned NOT NULL DEFAULT '0',  `addtime` int(11) unsigned NOT NULL,  `device` tinyint(1) unsigned NOT NULL DEFAULT '1' ,  PRIMARY KEY (`id`,`addtime`),  KEY `idx_accountid_addtime` (`accountid`,`addtime`),  KEY `idx_accountid_flag` (`accountid`,`flag`),) ENGINE=InnoDB AUTO_INCREMENT=50951039 DEFAULT CHARSET=utf8 COMMENT='操作记录'/*!50100 PARTITION BY RANGE (addtime)(PARTITION `2013-05` VALUES LESS THAN (1370016000) ENGINE = InnoDB, PARTITION `2013-06` VALUES LESS THAN (1372608000) ENGINE = InnoDB, PARTITION `2013-07` VALUES LESS THAN (1375286400) ENGINE = InnoDB, PARTITION `2013-08` VALUES LESS THAN (1377964800) ENGINE = InnoDB, PARTITION `2013-09` VALUES LESS THAN (1380556800) ENGINE = InnoDB, PARTITION `2013-10` VALUES LESS THAN (1383235200) ENGINE = InnoDB, PARTITION `2013-11` VALUES LESS THAN (1385827200) ENGINE = InnoDB, PARTITION `2013-12` VALUES LESS THAN (1388505600) ENGINE = InnoDB, PARTITION `2014-01` VALUES LESS THAN (1391184000) ENGINE = InnoDB, PARTITION `2014-02` VALUES LESS THAN (1393603200) ENGINE = InnoDB, PARTITION `2014-03` VALUES LESS THAN (1396281600) ENGINE = InnoDB, PARTITION `2014-04` VALUES LESS THAN (1398873600) ENGINE = InnoDB, PARTITION `2014-05` VALUES LESS THAN (1401552000) ENGINE = InnoDB, PARTITION `2014-06` VALUES LESS THAN (1404144000) ENGINE = InnoDB, PARTITION `2014-07` VALUES LESS THAN (1406822400) ENGINE = InnoDB, PARTITION `2014-08` VALUES LESS THAN (1409500800) ENGINE = InnoDB, PARTITION `2014-09` VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */1 row in set (0.00 sec)查看select如何使用分区mysql> explain partitions select id,accountid,cid,flag from operation_log where addtime="1369362524" /G ; *************************** 1. row ***************************   id: 1  select_type: SIMPLEtable: operation_log   partitions: 2013-05 type: ALLpossible_keys: NULL  key: NULL  key_len: NULL  ref: NULL rows: 4384356Extra: Using where1 row in set (0.00 sec)``分区表元数据统计表:INFORMATION_SCHEMA.PARTITIONS查看分区表operation_log的分区信息mysql> SELECT partition_name part, partition_expression expr, partition_description descr, table_rows FROM INFORMATION_SCHEMA.partitions WHERE TABLE_SCHEMA = schema() AND TABLE_NAME='operation_log';+---------+---------+------------+------------+| part| expr| descr | table_rows |+---------+---------+------------+------------+| 2013-05 | addtime | 1370016000 | 5999642 || 2013-06 | addtime | 1372608000 | 4579263 || 2013-07 | addtime | 1375286400 | 3223772 || 2013-08 | addtime | 1377964800 | 1995058 || 2013-09 | addtime | 1380556800 | 2497406 || 2013-10 | addtime | 1383235200 | 4106974 || 2013-11 | addtime | 1385827200 | 6209559 || 2013-12 | addtime | 1388505600 | 6415349 || 2014-01 | addtime | 1391184000 | 3953594 || 2014-02 | addtime | 1393603200 | 0 || 2014-03 | addtime | 1396281600 | 0 || 2014-04 | addtime | 1398873600 | 0 || 2014-05 | addtime | 1401552000 | 0 || 2014-06 | addtime | 1404144000 | 0 || 2014-07 | addtime | 1406822400 | 0 || 2014-08 | addtime | 1409500800 | 0 || 2014-09 | addtime | MAXVALUE | 0 |+---------+---------+------------+------------+17 rows in set (1.48 sec)
创建分区操作
RANGE分区:mysql> CREATE TABLE `operation_log` ( ->  `id` int(11) unsigned NOT NULL AUTO_INCREMENT, -> `cid` mediumint(7) unsigned NOT NULL, -> `accountid` mediumint(8) NOT NULL DEFAULT '0' , ->  `flag` tinyint(1) unsigned NOT NULL DEFAULT '0', ->  `addtime` int(11) unsigned NOT NULL, -> `device` tinyint(1) unsigned NOT NULL DEFAULT '1' , ->  PRIMARY KEY (`id`,`addtime`), -> KEY `idx_accountid_addtime` (`accountid`,`addtime`), ->  KEY `idx_accountid_flag` (`accountid`,`flag`), ->) ENGINE=InnoDB AUTO_INCREMENT=50951039 DEFAULT CHARSET=utf8 COMMENT='操作记录' ->/*!50100 PARTITION BY RANGE (addtime) ->(PARTITION `2013-05` VALUES LESS THAN (1370016000) ENGINE = InnoDB, -> PARTITION `2013-06` VALUES LESS THAN (1372608000) ENGINE = InnoDB, -> PARTITION `2013-07` VALUES LESS THAN (1375286400) ENGINE = InnoDB, -> PARTITION `2013-08` VALUES LESS THAN (1377964800) ENGINE = InnoDB, -> PARTITION `2013-09` VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */;1 row in set (0.00 sec)( LESS THAN MAXVALUE考虑到可能的最大值)list分区//这种方式失败mysql> CREATE TABLE IF NOT EXISTS `list_part` ( ->   `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户ID', ->   `province_id` int(2) NOT NULL DEFAULT 0 COMMENT '省', ->   `name` varchar(50) NOT NULL DEFAULT '' COMMENT '名称', ->   `sex` int(1) NOT NULL DEFAULT '0' COMMENT '0为男,1为女', ->   PRIMARY KEY (`id`) -> ) ENGINE=INNODB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 -> PARTITION BY LIST (province_id) ( -> PARTITION p0 VALUES IN (1,2,3,4,5,6,7,8), -> PARTITION p1 VALUES IN (9,10,11,12,16,21), -> PARTITION p2 VALUES IN (13,14,15,19), -> PARTITION p3 VALUES IN (17,18,20,22,23,24) -> );ERROR 1503 (HY000): A PRIMARY KEY must include all columns in the table's partitioning function//这种方式成功mysql> CREATE TABLE IF NOT EXISTS `list_part` ( ->   `id` int(11) NOT NULL  COMMENT '用户ID', ->   `province_id` int(2) NOT NULL DEFAULT 0 COMMENT '省', ->   `name` varchar(50) NOT NULL DEFAULT '' COMMENT '名称', ->   `sex` int(1) NOT NULL DEFAULT '0' COMMENT '0为男,1为女' -> ) ENGINE=INNODB  DEFAULT CHARSET=utf8 -> PARTITION BY LIST (province_id) ( -> PARTITION p0 VALUES IN (1,2,3,4,5,6,7,8), -> PARTITION p1 VALUES IN (9,10,11,12,16,21), -> PARTITION p2 VALUES IN (13,14,15,19), -> PARTITION p3 VALUES IN (17,18,20,22,23,24) -> );Query OK, 0 rows affected (0.33 sec)上面的这个创建list分区时,如果有主銉的话,分区时主键必须在其中,不然就会报错。如果我不用主键,分区就创建成功了,一般情况下,一个张表肯定会有一个主键,这算是一个分区的局限性hash分区mysql> CREATE TABLE IF NOT EXISTS `hash_part` ( ->   `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '评论ID', ->   `comment` varchar(1000) NOT NULL DEFAULT '' COMMENT '评论', ->   `ip` varchar(25) NOT NULL DEFAULT '' COMMENT '来源IP', ->   PRIMARY KEY (`id`) -> ) ENGINE=INNODB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 -> PARTITION BY HASH(id) -> PARTITIONS 3;Query OK, 0 rows affected (0.06 sec)key分区 mysql> CREATE TABLE IF NOT EXISTS `key_part` ( ->   `news_id` int(11) NOT NULL  COMMENT '新闻ID', ->   `content` varchar(1000) NOT NULL DEFAULT '' COMMENT '新闻内容', ->   `u_id` varchar(25) NOT NULL DEFAULT '' COMMENT '来源IP', ->   `create_time` DATE NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '时间' -> ) ENGINE=INNODB  DEFAULT CHARSET=utf8 -> PARTITION BY LINEAR HASH(YEAR(create_time)) -> PARTITIONS 3;Query OK, 0 rows affected (0.07 sec)

增加子分区操作:

子分区是分区表中每个分区的再次分割,子分区既可以使用HASH希分区,也可以使用KEY分区。这 也被称为复合分区(composite partitioning)。

1. 如果一个分区中创建了子分区,其他分区也要有子分区2. 如果创建了了分区,每个分区中的子分区数必有相同3. 同一分区内的子分区,名字不相同,不同分区内的子分区名子可以相同(5.1.50不适用) mysql> CREATE TABLE IF NOT EXISTS `sub_part` ( ->   `news_id` int(11) NOT NULL  COMMENT '新闻ID', ->   `content` varchar(1000) NOT NULL DEFAULT '' COMMENT '新闻内容', ->   `u_id` int(11) NOT NULL DEFAULT 0s COMMENT '来源IP', ->   `create_time` DATE NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '时间' -> ) ENGINE=INNODB  DEFAULT CHARSET=utf8 -> PARTITION BY RANGE(YEAR(create_time)) -> SUBPARTITION BY HASH(TO_DAYS(create_time))( -> PARTITION p0 VALUES LESS THAN (1990)(SUBPARTITION s0,SUBPARTITION s1,SUBPARTITION s2), -> PARTITION p1 VALUES LESS THAN (2000)(SUBPARTITION s3,SUBPARTITION s4,SUBPARTITION good), -> PARTITION p2 VALUES LESS THAN MAXVALUE(SUBPARTITION tank0,SUBPARTITION tank1,SUBPARTITION tank3) -> );Query OK, 0 rows affected (0.07 sec)

分区管理:

增加分区操作(针对设置MAXVALUE) range添加分区mysql>alter table operation_log add  partition(partition `2013-10` values less than (1383235200));  --->适用于没有设置MAXVALUE的分区添加   ERROR 1481 (HY000):MAXVALUE can only be used in last partition definitionmysql>alter table operation_log REORGANIZE partition `2013-09` into (partition `2013-09` values less than (1380556800),partition `2013-10` values less than (1383235200),partition `2013-11` values less than maxvalue); list添加分区mysql> alter table list_part add partition(partition p4 values in (25,26,28));Query OK, 0 rows affected (0.01 sec)Records: 0  Duplicates: 0  Warnings: 0 hash重新分区mysql> alter table list_part add partition(partition p4 values in (25,26,28));Query OK, 0 rows affected (0.01 sec)Records: 0  Duplicates: 0  Warnings: 0 key重新分区mysql> alter table key_part add partition partitions 4;Query OK, 1 row affected (0.06 sec)//有数据也会被重新分配Records: 1  Duplicates: 0  Warnings: 0子分区添加新分区,虽然我没有指定子分区,但是系统会给子分区命名的mysql> alter table sub1_part add partition(partition p3 values less than MAXVALUE);Query OK, 0 rows affected (0.02 sec)Records: 0  Duplicates: 0  Warnings: 0

删除分区操作

alter table user drop partition `2013-05`;
分区表其他操作
重建分区(官方:与先drop所有记录然后reinsert是一样的效果;用于整理表碎片)alter table operation_log rebuild partition `2014-01`;重建多个分区alter table operation_log rebuild partition `2014-01`,`2014-02`;过程如下:pro优化分区(如果删除了一个分区的大量记录或者对一个分区的varchar blob text数据类型的字段做了许多更新,此时可以对分区进行优化以回收未使用的空间和整理分区数据文件)alter table operation_log  optimize  partition `2014-01`;优化的操作相当于check partition,analyze partition 和repair patition分析分区alter table operation_log  analyze partition  `2014-01`;修复分区alter table operation_log repair partition   `2014-01`;检查分区alter table operation_log check  partition   `2014-01`;

注释:

  1. mysqlcheck、myisamchk并不支持分区表,analyze,check,optimize,rebuild,repair,truncate不支持子分区操作
  2. 在MySQL5.6中,可以使用清空一个分区数据:alter table operation_log truncate partition 2014-01;
  3. 清空该分区表所有分区数据:alter table operation_log truncate partition all;

参考文档:

http://blog.51yip.com/mysql/1013.html

https://dev.mysql.com/doc/refman/5.6/en/partitioning-maintenance.html

http://dev.mysql.com/doc/refman/5.6/en/index.html

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
您什麼時候應該使用複合索引與多個單列索引?您什麼時候應該使用複合索引與多個單列索引?Apr 11, 2025 am 12:06 AM

在數據庫優化中,應根據查詢需求選擇索引策略:1.當查詢涉及多個列且條件順序固定時,使用複合索引;2.當查詢涉及多個列但條件順序不固定時,使用多個單列索引。複合索引適用於優化多列查詢,單列索引則適合單列查詢。

如何識別和優化MySQL中的慢速查詢? (慢查詢日誌,performance_schema)如何識別和優化MySQL中的慢速查詢? (慢查詢日誌,performance_schema)Apr 10, 2025 am 09:36 AM

要優化MySQL慢查詢,需使用slowquerylog和performance_schema:1.啟用slowquerylog並設置閾值,記錄慢查詢;2.利用performance_schema分析查詢執行細節,找出性能瓶頸並優化。

MySQL和SQL:開發人員的基本技能MySQL和SQL:開發人員的基本技能Apr 10, 2025 am 09:30 AM

MySQL和SQL是開發者必備技能。 1.MySQL是開源的關係型數據庫管理系統,SQL是用於管理和操作數據庫的標準語言。 2.MySQL通過高效的數據存儲和檢索功能支持多種存儲引擎,SQL通過簡單語句完成複雜數據操作。 3.使用示例包括基本查詢和高級查詢,如按條件過濾和排序。 4.常見錯誤包括語法錯誤和性能問題,可通過檢查SQL語句和使用EXPLAIN命令優化。 5.性能優化技巧包括使用索引、避免全表掃描、優化JOIN操作和提升代碼可讀性。

描述MySQL異步主奴隸複製過程。描述MySQL異步主奴隸複製過程。Apr 10, 2025 am 09:30 AM

MySQL異步主從復制通過binlog實現數據同步,提升讀性能和高可用性。 1)主服務器記錄變更到binlog;2)從服務器通過I/O線程讀取binlog;3)從服務器的SQL線程應用binlog同步數據。

mysql:簡單的概念,用於輕鬆學習mysql:簡單的概念,用於輕鬆學習Apr 10, 2025 am 09:29 AM

MySQL是一個開源的關係型數據庫管理系統。 1)創建數據庫和表:使用CREATEDATABASE和CREATETABLE命令。 2)基本操作:INSERT、UPDATE、DELETE和SELECT。 3)高級操作:JOIN、子查詢和事務處理。 4)調試技巧:檢查語法、數據類型和權限。 5)優化建議:使用索引、避免SELECT*和使用事務。

MySQL:數據庫的用戶友好介紹MySQL:數據庫的用戶友好介紹Apr 10, 2025 am 09:27 AM

MySQL的安裝和基本操作包括:1.下載並安裝MySQL,設置根用戶密碼;2.使用SQL命令創建數據庫和表,如CREATEDATABASE和CREATETABLE;3.執行CRUD操作,使用INSERT,SELECT,UPDATE,DELETE命令;4.創建索引和存儲過程以優化性能和實現複雜邏輯。通過這些步驟,你可以從零開始構建和管理MySQL數據庫。

InnoDB緩衝池如何工作,為什麼對性能至關重要?InnoDB緩衝池如何工作,為什麼對性能至關重要?Apr 09, 2025 am 12:12 AM

InnoDBBufferPool通過將數據和索引頁加載到內存中來提升MySQL數據庫的性能。 1)數據頁加載到BufferPool中,減少磁盤I/O。 2)臟頁被標記並定期刷新到磁盤。 3)LRU算法管理數據頁淘汰。 4)預讀機制提前加載可能需要的數據頁。

MySQL:初學者的數據管理易用性MySQL:初學者的數據管理易用性Apr 09, 2025 am 12:07 AM

MySQL適合初學者使用,因為它安裝簡單、功能強大且易於管理數據。 1.安裝和配置簡單,適用於多種操作系統。 2.支持基本操作如創建數據庫和表、插入、查詢、更新和刪除數據。 3.提供高級功能如JOIN操作和子查詢。 4.可以通過索引、查詢優化和分錶分區來提升性能。 5.支持備份、恢復和安全措施,確保數據的安全和一致性。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具