數據庫(五):約束關系


進擊のpython

*****

數據庫——約束條件


+-------+---------------------------+------+-----+---------+-------+
| Field | Type                      | Null | Key | Default | Extra |
+-------+---------------------------+------+-----+---------+-------+
| id    | int(11)                   | YES  |     | NULL    |       |
| name  | char(6)                   | YES  |     | NULL    |       |
| sex   | enum('male','female')     | YES  |     | NULL    |       |
| hobby | set('sing','dance','Rap') | YES  |     | NULL    |       |
+-------+---------------------------+------+-----+---------+-------+

這個表你很熟悉吧,這其中的Null和Default就是約束條件

那其實不光有這些約束條件,在規定int的時候的unsigned也是約束條件

那本節就是針對約束條件來進行展開的


not null與default

Null是指該數據可以為空,Default是該參數的默認值,就好像python中的默認參數一樣

那我們現在就針對這個進行操作

create table t8(id int,name char(6),sex enum('male','female') not null default "male");

mysql> create table t8(
    ->
    -> id int,
    ->
    -> name char(6),
    ->
    -> sex enum('male','female') not null default "male"
    ->
    -> );
Query OK, 0 rows affected (0.57 sec)

mysql> desc t8;
+-------+-----------------------+------+-----+---------+-------+
| Field | Type                  | Null | Key | Default | Extra |
+-------+-----------------------+------+-----+---------+-------+
| id    | int(11)               | YES  |     | NULL    |       |
| name  | char(6)               | YES  |     | NULL    |       |
| sex   | enum('male','female') | NO   |     | male    |       |
+-------+-----------------------+------+-----+---------+-------+
3 rows in set (0.06 sec)

那現在開始進行傳值:

mysql> insert into t8(id,name) values(1,'ponny');
Query OK, 1 row affected (0.37 sec)

mysql> select * from t8;
+------+-------+------+
| id   | name  | sex  |
+------+-------+------+
|    1 | ponny | male |
+------+-------+------+
1 row in set (0.00 sec)

那你就可以看到,這個sex這個屬性,在我沒有進行傳值的時候,庫中使用的就是默認值


unique

那null和default我們都了解完畢之后,接下來我們就開始對key進行研究

key有一個約束條件叫做unique,叫做唯一性約束,本意就是這個鍵不能重復

我們可能都默認的傳數據使得每一個值都不唯一,但其實不限制,是可以重復的

那為了不讓數據重復,我們就有需要加上約束(對原表進行操作,練習命令):

mysql> alter table t8 change id id int unique;
Query OK, 0 rows affected (0.89 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc t8;
+-------+-----------------------+------+-----+---------+-------+
| Field | Type                  | Null | Key | Default | Extra |
+-------+-----------------------+------+-----+---------+-------+
| id    | int(11)               | YES  | UNI | NULL    |       |
| name  | char(6)               | YES  |     | NULL    |       |
| sex   | enum('male','female') | NO   |     | male    |       |
+-------+-----------------------+------+-----+---------+-------+
3 rows in set (0.01 sec)

這樣id的值就不會重復了,院線數據中有個id=1的數據,我們看看再存1可不可以

mysql> insert into t8(id,name) values(1,'tom');
ERROR 1062 (23000): Duplicate entry '1' for key 'id'

如果有還添加就會出現這樣的報錯

那除了這樣的唯一,還有一種叫做聯合唯一的東西

什么叫做聯合唯一呢?舉個例子:

A:name:ponny id:2

B:name:tom id:2

這兩個數據中某一部分相等,但是整體不同,這就是整體唯一所帶來的效果

多數據中只有一個唯一限制,其實就是聯合限制


primary key

primary key 主鍵

他的約束就比較干凈利落,相當於 not null unique 還記得表的默認引擎是什么嗎?innodb對吧

在innodb引擎對主鍵是有規定的:一張表必須有一個主鍵 不對啊!前面的表都沒有主鍵啊!不是也能創建成功嗎?

是這樣的,MySQL數據庫是有一種機制,在創建表的時候,他會先看看有沒有規定主鍵

沒有規定?ok,再去找有沒有符合 not null unique 這種約束的,把第一個出現這種約束的當做主鍵

也沒有?ok,那這樣的話,MySQL就會自己偷偷地再創建一個字段,當做主鍵

但是最后一種情況很明顯,擴大了內存,畢竟自己偷偷地又創建了一個字段

同時,倒數第二種情況意味着你要同樣的表查兩遍,就會降低速度(一點速度也是速度啊!!!!)

所以說,就可以看出來,還是要規定主鍵的!!!

那主鍵其實也是有兩種的:

單列主鍵

一般情況下都是id設為主鍵,先記着,后面再說為什么

create table t9(id int primary key,name char(5));

mysql> create table t9(id int primary key,name char(5));
Query OK, 0 rows affected (1.00 sec)

mysql> desc t9;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id    | int(11) | NO   | PRI | NULL    |       |
| name  | char(5) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.08 sec)

就可以看到,這個key的類型是PRI,也就是主鍵的意思,同時也看到null是NO

至於為空和唯一,就自己試試好吧~~

復合主鍵

復合主鍵就像聯合唯一那樣,單個數據可以相同但是總體數據不能相同,改造一下t9表:

mysql> alter table t9 add sex enum('famale','male');
Query OK, 0 rows affected (1.44 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> alter table t9 add tel int;
Query OK, 0 rows affected (0.88 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc t9;
+-------+-----------------------+------+-----+---------+-------+
| Field | Type                  | Null | Key | Default | Extra |
+-------+-----------------------+------+-----+---------+-------+
| id    | int(11)               | NO   | PRI | NULL    |       |
| name  | char(5)               | YES  |     | NULL    |       |
| sex   | enum('famale','male') | YES  |     | NULL    |       |
| tel   | int(11)               | YES  |     | NULL    |       |
+-------+-----------------------+------+-----+---------+-------+
4 rows in set (0.01 sec)

現在我想id和tel設為復合主鍵,肯定有同學要這么寫:

alter table t9 add primary key (id,tel);

執行之后會出現什么情況呢???

mysql> alter table t9 add primary key (id,tel);
ERROR 1068 (42000): Multiple primary key defined

這個錯誤就大概是你有多個主鍵,所以不行這么操作

復合主鍵講究的是,同時創建,對於這種情況,操作方法就是先把原先的主鍵刪掉,再創建復合主鍵

alter table t9 drop primary key;

mysql> alter table t9 drop primary key;
Query OK, 0 rows affected (1.69 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc t9;
+-------+-----------------------+------+-----+---------+-------+
| Field | Type                  | Null | Key | Default | Extra |
+-------+-----------------------+------+-----+---------+-------+
| id    | int(11)               | NO   |     | NULL    |       |
| name  | char(5)               | YES  |     | NULL    |       |
| sex   | enum('famale','male') | YES  |     | NULL    |       |
| tel   | int(11)               | YES  |     | NULL    |       |
+-------+-----------------------+------+-----+---------+-------+
4 rows in set (0.01 sec)

然后再創建復合主鍵:

alter table t9 add primary key(id,tel);

mysql> alter table t9 add primary key(id,tel);
Query OK, 0 rows affected (1.49 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc t9;
+-------+-----------------------+------+-----+---------+-------+
| Field | Type                  | Null | Key | Default | Extra |
+-------+-----------------------+------+-----+---------+-------+
| id    | int(11)               | NO   | PRI | NULL    |       |
| name  | char(5)               | YES  |     | NULL    |       |
| sex   | enum('famale','male') | YES  |     | NULL    |       |
| tel   | int(11)               | NO   | PRI | 0       |       |
+-------+-----------------------+------+-----+---------+-------+
4 rows in set (0.01 sec)

這是有表修改的方法,也可以在創建表的時候直接定義復合主鍵:

create table t10(

id int,

name char(6),

tel int,

primary key(id,tel)

);
# 橫着寫會,豎着寫就不會了????
mysql> create table t10(
    ->
    -> id int,
    ->
    -> name char(6),
    ->
    -> tel int,
    ->
    -> primary key(id,tel)
    ->
    -> );
Query OK, 0 rows affected (1.11 sec)

mysql> desc t10;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id    | int(11) | NO   | PRI | 0       |       |
| name  | char(6) | YES  |     | NULL    |       |
| tel   | int(11) | NO   | PRI | 0       |       |
+-------+---------+------+-----+---------+-------+
3 rows in set (0.01 sec)

正好借着新建的這個表來驗證一下復合主鍵的特性:

insert into t10(id,tel) values(1,1);

insert into t10(id,tel) values(2,1);

insert into t10(id,tel) values(1,2);

insert into t10(id,tel) values(2,1);
mysql> insert into t10(id,tel) values(1,1);
Query OK, 1 row affected (0.54 sec)

mysql>
mysql> insert into t10(id,tel) values(2,1);
Query OK, 1 row affected (0.05 sec)

mysql>
mysql> insert into t10(id,tel) values(1,2);
Query OK, 1 row affected (0.12 sec)

mysql>
mysql> insert into t10(id,tel) values(2,1);
ERROR 1062 (23000): Duplicate entry '2-1' for key 'PRIMARY'

mysql> select * from t10;
+----+------+-----+
| id | name | tel |
+----+------+-----+
|  1 | NULL |   1 |
|  1 | NULL |   2 |
|  2 | NULL |   1 |
+----+------+-----+
3 rows in set (0.00 sec)

前面的都添加成功了,而傳入(2,1)的值提示的是,已經有了對吧~所以沒有添加進去


auto_increment

自增約束

創建表格的時候,其實都默認的寫了一個字段 id

那你有沒有想過這個id是干什么用的?其實這個id是用來標志這是第幾條記錄的

那既然是標識是第幾條記錄的,那我們有沒有一種方法,讓它自動生成而不用我們自己寫?

我們想要的效果是每插入一條記錄,他就自動的加一,這是最好的對吧,所以自增就出現了

那一般約束條件都是直接在類型后面直接加對吧

create table t11(id int auto_increment);

mysql> create table t11(id int auto_increment);
ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key

他給我報了一個錯誤,什么錯誤呢?表類型錯誤,說一個表只能有一個自增,而且他還必須是鍵

我們現在學過哪幾種建?一個是unique,一個是primary key

前面也提過,id最好設置為主鍵,所以上面的命令應該再優化一下:

create table t11(id int primary key auto_increment);

mysql> create table t11(id int primary key auto_increment);
Query OK, 0 rows affected (0.99 sec)

mysql> desc t11;
+-------+---------+------+-----+---------+----------------+
| Field | Type    | Null | Key | Default | Extra          |
+-------+---------+------+-----+---------+----------------+
| id    | int(11) | NO   | PRI | NULL    | auto_increment |
+-------+---------+------+-----+---------+----------------+
1 row in set (0.01 sec)

那我再添加一個名字的字段(自己用指令添加)

那既然是自增長的 也就意味着我可以不用傳id值,他會自動幫我處理

mysql> insert into t11(name) values('ponny'),('Tom');
Query OK, 2 rows affected (0.39 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from t11;
+----+-------+
| id | name  |
+----+-------+
|  1 | ponny |
|  2 | Tom   |
+----+-------+
2 rows in set (0.00 sec)

和我們想要的效果是一樣的~達到了自己添加,id自動增長,從1開始,每次增長1個

id可以不寫,那我要是非要寫呢?可不可以添加成功呢?

mysql> insert into t11(id,name) values(5,"Jerry");
Query OK, 1 row affected (0.40 sec)

mysql> select * from t11;
+----+-------+
| id | name  |
+----+-------+
|  1 | ponny |
|  2 | Tom   |
|  5 | Jerry |
+----+-------+
3 rows in set (0.00 sec)

是可以添加成功的,那么我接下來再自增會出現什么情況呢?

mysql> insert into t11(name) values('ponny'),('Tom');
Query OK, 2 rows affected (0.38 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from t11;
+----+-------+
| id | name  |
+----+-------+
|  1 | ponny |
|  2 | Tom   |
|  5 | Jerry |
|  6 | ponny |
|  7 | Tom   |
+----+-------+
5 rows in set (0.00 sec)

你會發現他不是在斷的地方進行自增,而是以最后一組記錄的id來進行的自增

還有個問題,我能不能指定他的起始,指定他一次增多少呢?

你別說,MySQL還真的提供了這個方法,我們可以先看一下他的默認設置

show variables like 'auto_inc%'

其中like就是模糊匹配,現在不說,這個%的意思是我要的是auto_inc開頭的

當然,如果你能把increment全部拼出來,就不需要這個%了

mysql> show variables like 'auto_inc%';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| auto_increment_increment | 1     |
| auto_increment_offset    | 1     |
+--------------------------+-------+
2 rows in set (0.00 sec)

可以看到兩條設置 increment:步長;offset:起始位置

可以看到后面都是1,代表着,從1增加,每次增加1

那既然能拿到,就能夠設置,在設置上也有兩種操作

分別是:set session 和 set global

set session 只對當次有效

set global 一直有效

設置步長:set global auto_increment_increment=5;

設置起始位置這就有說法了!

起始位置其實叫做起始偏移量,就相當於我已經走出去一步了,所以不應該超過步長才對

但是可以小於等於步長,也就意味着,如果設置超過了,起始位置就無效了

設置起始:set global auto_increment_offset=3;

mysql> set global auto_increment_increment=5;
Query OK, 0 rows affected (0.00 sec)

mysql> set global auto_increment_offset=3;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like 'auto_inc%';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| auto_increment_increment | 1     |
| auto_increment_offset    | 1     |
+--------------------------+-------+
2 rows in set (0.00 sec)

設置之后你發現,誒?怎么沒變呢??原因是我們應該更新一下,就是退了重進

當我重進一下就變成了:

mysql> show variables like 'auto_inc%';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| auto_increment_increment | 5     |
| auto_increment_offset    | 3     |
+--------------------------+-------+
2 rows in set (0.00 sec)

那我們試一下:

mysql> insert into t11(name) values("da"),("daw");
Query OK, 2 rows affected (0.07 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from t11;
+----+-------+
| id | name  |
+----+-------+
|  1 | ponny |
|  2 | Tom   |
|  5 | Jerry |
|  6 | ponny |
|  7 | Tom   |
|  8 | da    |
| 13 | daw   |
+----+-------+
7 rows in set (0.00 sec)

看,是不是從8直接到13了~

這里有一個現象:

mysql> delete from t11;
Query OK, 7 rows affected (0.48 sec)

mysql> select * from t11;
Empty set (0.00 sec)

mysql> insert into t11(name) values('sa'),('de');
Query OK, 2 rows affected (0.38 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from t11;
+----+------+
| id | name |
+----+------+
| 18 | sa   |
| 23 | de   |
+----+------+
2 rows in set (0.00 sec)

你會發現,即使刪掉了,他還是會繼續自增,這不是我們想要的效果

這個時候你說啊~我自己個給id也行,是也行,但是我們還是沒有解決刪干凈這個問題

所以新的命令就出現了truncate t11;

mysql> truncate t11;
Query OK, 0 rows affected (0.54 sec)

mysql> insert into t11(name) values('sa'),('de');
Query OK, 2 rows affected (0.07 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from t11;
+----+------+
| id | name |
+----+------+
|  3 | sa   |
|  8 | de   |
+----+------+
2 rows in set (0.00 sec)

這是不是才是真正的達到了我們的要求啊~

通過這個例子我們可以看出,刪表不建議delete,而應該使用truncate

delete的使用往往是跟着where連用的~


foreign key

在實際操作中,並不是只有一個表的,比如一個公司

員工要在各個部門上班,各個部門又有各個部門的信息

那講道理你不能把員工信息和部門信息放在一張表里吧

姓名 部門 部門負責人 部門電話 ...
Tom 研發 Alisa 135XXXXXXXX ...
Jerry 產品 John 173XXXXXXXX ...
Jevious 產品 John 173XXXXXXXX ...
Ponny 研發 Alisa 135XXXXXXXX ...
Daddy 事務 Kin 186XXXXXXXX ...

就可以看出來,同一張表格里相同信息多不多?多!

而且還有問題,部門負責人永遠都是XXX?不會換人?要是換人,這些數據都要改

而且 XXX一直都在XXX部門?也不一定吧,要是部門一改,那后面所有都要改

要是照這種表結構,這就十分的麻煩~我們可以怎么做呢?我們可以把表拆開

姓名 ...
Tom ...
Jerry ...
Jevious ...
Ponny ...
Daddy ...
部門 部門負責人 部門電話 ...
研發 Alisa 135XXXXXXXX ...
產品 John 173XXXXXXXX ...
事務 Kin 186XXXXXXXX ...

上面提出的問題就已經完美解決了,但是這兩個表格聯系上了嗎?很明顯沒有,而且員工確實應該有部門

那我們表格就可以這么設置:

姓名 部門ID ...
Tom 1 ...
Jerry 2 ...
Jevious 2 ...
Ponny 1 ...
Daddy 3 ...
部門ID 部門 部門負責人 部門電話 ...
1 研發 Alisa 135XXXXXXXX ...
2 產品 John 173XXXXXXXX ...
3 事務 Kin 186XXXXXXXX ...

這樣是不是就通過部門id 讓兩個表有了聯系

但是同理也出來了,如果還有個擴展表格,比如部門負責人信息,也像部門這樣分離出來

id取得也是1 2 3 ,那員工表里面的部門id的1 2 3指的是部門表還是部門信息表?

是不是沒有硬性規定說我的這個部門id就是來自於部門這個表

所以我們需要給他個硬性規定,foreign key 外鍵就出現了

create table staff(
id int primary key,
name char(10),
department_id int,
foreign key (department_id) references department(id)
);

但是你要是綁定的前提是不是得有這張表啊:

create table department(
id int primary key,
name char(5),
leader char(10),
tel char(11)
);
mysql> create table department(
    -> id int primary key,
    -> name char(5),
    -> leader char(10),
    -> tel char(11)
    -> );
Query OK, 0 rows affected (0.74 sec)

mysql> create table staff(
    -> id int primary key,
    -> name char(10),
    -> department_id int,
    -> foreign key (department_id) references department(id)
    -> );
Query OK, 0 rows affected (0.52 sec)

mysql> show tables;
+-------------+
| Tables_in_t |
+-------------+
| department  |
| staff       |
+-------------+
2 rows in set (0.05 sec)

表建好了,就是寫入記錄,其實還是一樣,要先寫被關聯的表

你想啊,你不先寫被關聯的表,你關聯誰啊?,所以我們先對被關聯的表進行賦值

insert into department values

(1,'研發','Alisa','135XXXXXXXX'),

(2,'產品','John','173XXXXXXXX'),

(3,'事務','Kin','186XXXXXXXX');
mysql> insert into department values
    ->
    -> (1,'研發','Alisa','135XXXXXXXX'),
    ->
    -> (2,'產品','John','173XXXXXXXX'),
    ->
    -> (3,'事務','Kin','186XXXXXXXX')
    -> ;
Query OK, 3 rows affected (0.23 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> select * from department;
+----+--------+--------+-------------+
| id | name   | leader | tel         |
+----+--------+--------+-------------+
|  1 | 研發   | Alisa  | 135XXXXXXXX |
|  2 | 產品   | John   | 173XXXXXXXX |
|  3 | 事務   | Kin    | 186XXXXXXXX |
+----+--------+--------+-------------+
3 rows in set (0.01 sec)

建立主表

insert into staff values

(1,'Tom',1),

(2,'Jerry',2),

(3,'Jevious',2),

(4,'Ponny',1),

(5,'Daddy',3);
mysql> insert into staff values
    ->
    -> (1,'Tom',1),
    ->
    -> (2,'Jerry',2),
    ->
    -> (3,'Jevious',2),
    ->
    -> (4,'Ponny',1),
    ->
    -> (5,'Daddy',3);
Query OK, 5 rows affected (0.41 sec)
Records: 5  Duplicates: 0  Warnings: 0

mysql> select * from staff;
+----+---------+---------------+
| id | name    | department_id |
+----+---------+---------------+
|  1 | Tom     |             1 |
|  2 | Jerry   |             2 |
|  3 | Jevious |             2 |
|  4 | Ponny   |             1 |
|  5 | Daddy   |             3 |
+----+---------+---------------+
5 rows in set (0.00 sec)

代碼都是根據需求來的,假設有一天,事務部解散了,數據要怎么辦呢?

很明顯要先刪掉員工表里department_id=3的,而不應該先去刪department這個表

因為先刪department,就會讓staff表里的關聯到事務的記錄的最后一項變得沒有意義

(這部分的描述要是不理解可以自己實際操作,刪掉 事務 部門)

那,我這要想解散一個部門還要多表聯動?這是兩個表,這表要是多點,也就牽一發動全身

所以有沒有什么好辦法,能讓解散變得簡單點呢?我刪掉部門,和這個關聯的都刪掉

實際上,在外鍵的設定上還有幾個參數沒介紹:

on delete cascade 刪除同步

on update cascade 更新同步

那我們重新建立:

create table staff(
id int primary key,
name char(10),
department_id int,
foreign key (department_id) references department(id) on delete cascade on update cascade
);

其他的都跟上面一樣,那我們來試試可不可以直接刪部門!

mysql> delete from department where id = 3;
Query OK, 1 row affected (0.41 sec)

mysql> select * from staff;
+----+---------+---------------+
| id | name    | department_id |
+----+---------+---------------+
|  1 | Tom     |             1 |
|  2 | Jerry   |             2 |
|  3 | Jevious |             2 |
|  4 | Ponny   |             1 |
+----+---------+---------------+
4 rows in set (0.00 sec)

mysql> select * from department;
+----+--------+--------+-------------+
| id | name   | leader | tel         |
+----+--------+--------+-------------+
|  1 | 研發   | Alisa  | 135XXXXXXXX |
|  2 | 產品   | John   | 173XXXXXXXX |
+----+--------+--------+-------------+
2 rows in set (0.00 sec)

這是不是我們想要的效果完美

那我們再試試修改:

mysql> update department set id=3 where id = 2;
Query OK, 1 row affected (0.43 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from department;
+----+--------+--------+-------------+
| id | name   | leader | tel         |
+----+--------+--------+-------------+
|  1 | 研發   | Alisa  | 135XXXXXXXX |
|  3 | 產品   | John   | 173XXXXXXXX |
+----+--------+--------+-------------+
2 rows in set (0.00 sec)

mysql> select * from staff;
+----+---------+---------------+
| id | name    | department_id |
+----+---------+---------------+
|  1 | Tom     |             1 |
|  2 | Jerry   |             3 |
|  3 | Jevious |             3 |
|  4 | Ponny   |             1 |
+----+---------+---------------+
4 rows in set (0.00 sec)

當我將部門的編號修改之后,看,原關聯表也進行了修改!這就是最完美的關聯!

但是!!!!

!!!!!!

不推薦使用外鍵!

為什么?因為這么寫無異於將兩個表耦合在一起了,對於擴展來說是十分不友好的

我們應該做的,是讓兩個表的邏輯相關聯,通過代碼邏輯讓其產生聯系,而讓每個表都是獨立的個體

所以不建議這樣做出硬性關聯!


*****
*****


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM