最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL和KingbaseES中連接、對象命名空間及用戶權(quán)限的區(qū)別

 更新時(shí)間:2026年06月13日 11:19:41   作者:一只牛博  
這段文章詳細(xì)解釋了KingbaseES中連接數(shù)據(jù)庫、對象命名空間及登錄用戶之間的區(qū)別,指出MySQL習(xí)慣的開發(fā)者容易混淆這些概念,文章通過實(shí)驗(yàn)展示了在不同schema和search_path下,同一個(gè)表名可能指向不同的對象,強(qiáng)調(diào)開發(fā)者在寫SQL時(shí)需明確schema前前綴,以避免查詢錯(cuò)誤

先準(zhǔn)備一個(gè)普通用戶 app_user 和一個(gè)數(shù)據(jù)庫 app_db。如果按 MySQL 的習(xí)慣看,很容易把事情理解成:連上 app_db,表就建在 app_db 下面。

這個(gè)理解在日??陬^表達(dá)里問題不大,但繼續(xù)寫 SQL 時(shí)會很快遇到麻煩。KingbaseES 里,連接目標(biāo)、對象命名空間、登錄用戶是三件事:

database:連接到哪個(gè)數(shù)據(jù)庫
schema:表、視圖、函數(shù)這些對象放在哪個(gè)命名空間
user/role:當(dāng)前是誰在執(zhí)行操作

MySQL 里經(jīng)常把 database 當(dāng)作命名空間使用,寫 db_name.table_name 很常見。KingbaseES 這里更需要先適應(yīng) schema.table 這層關(guān)系。不把這件事分清楚,后面很容易出現(xiàn)表明明存在卻查不到、同一個(gè)表名查到的不是預(yù)期數(shù)據(jù)、換個(gè)用戶以后對象顯示不一樣這些問題。

這不是概念潔癖。開發(fā)時(shí)最常見的低級問題,往往不是 SQL 函數(shù)不會用,而是連錯(cuò)庫、建錯(cuò)位置、查錯(cuò)對象。MySQL 里執(zhí)行 use app_db; 以后,再 show tables;,心里通常會默認(rèn)“當(dāng)前庫里的表就在這里”。到了 KingbaseES,連接到 app_db 以后,還要多看一層:當(dāng)前 schema 是誰,默認(rèn)對象查找順序是什么。

如果只做一個(gè)簡單表,這個(gè)差別不明顯。一旦開始做遷移、按模塊拆 schema、給不同用戶分配對象,差別就會變得很具體。一個(gè)庫里可能有 public.t_order,也可能有 archive.t_orderreport.t_order。不帶 schema 前綴的 select * from t_order 到底查哪張表,不能只靠表名判斷。

下面的實(shí)驗(yàn)只用兩個(gè)對象名:一個(gè)普通用戶 app_user,一個(gè)數(shù)據(jù)庫 app_db。表名也故意復(fù)用 t_schema_demo,讓它分別出現(xiàn)在 publicapp_schema 下面。這樣能把問題壓到最?。和粋€(gè) database、同一個(gè) user、同一個(gè)表名,只因?yàn)?schema 和 search_path 不同,查詢結(jié)果就會變。

當(dāng)前連接里不只有數(shù)據(jù)庫名

先用普通用戶連接數(shù)據(jù)庫:

ksql -h 127.0.0.1 -p 54321 -U app_user -d app_db

進(jìn)入 ksql 后查三個(gè)值:

select current_database(), current_user, current_schema();
show search_path;

返回結(jié)果里,當(dāng)前數(shù)據(jù)庫是 app_db,當(dāng)前用戶是 app_user,當(dāng)前 schema 是 publicsearch_path 是:

"$user", public

這里已經(jīng)能看到幾個(gè)概念被拆開了。連接命令里的 -d app_db 只決定當(dāng)前 database;登錄命令里的 -U app_user 決定當(dāng)前用戶;真正不寫前綴建表時(shí)會落到哪里,還要看當(dāng)前 schema 和 search_path。

"$user", public 的意思是:先嘗試找和當(dāng)前用戶同名的 schema,再找 public。當(dāng)前環(huán)境里沒有 app_user 這個(gè) schema,所以 current_schema() 返回的是 public。

這一步對 MySQL 用戶很關(guān)鍵。連到 app_db 不等于后面所有對象都直接掛在 app_db 這一層,表還會屬于某個(gè) schema。

可以把這組信息拆成一句話:app_user 以某個(gè)用戶身份連接到了 app_db,當(dāng)前默認(rèn)會在 public schema 里創(chuàng)建和查找對象。三個(gè)值分別回答三個(gè)問題:

current_database()  當(dāng)前連接哪個(gè)數(shù)據(jù)庫
current_user        當(dāng)前用哪個(gè)用戶執(zhí)行
current_schema()    當(dāng)前默認(rèn)使用哪個(gè) schema

show search_path; 則回答另一個(gè)問題:沒寫 schema 前綴時(shí),數(shù)據(jù)庫按什么順序找對象。這個(gè)配置不只是顯示信息,它會直接影響建表和查表。

不寫 schema,表會落到默認(rèn)位置

直接建一張表:

drop table if exists t_schema_demo;
create table t_schema_demo(id int, name varchar(50));
insert into t_schema_demo values (1, 'from default schema');

再用 \dt\d 看對象:

\dt
\d t_schema_demo

同時(shí)查系統(tǒng)視圖:

select schemaname, tablename, tableowner
from sys_tables
where tablename = 't_schema_demo';

結(jié)果很直接,t_schema_demopublic 下,owner 是 app_user。

這就是 search_path 生效后的結(jié)果。建表語句沒有寫 public.t_schema_demo,但當(dāng)前默認(rèn) schema 是 public,所以表落到了 public

換成 MySQL 習(xí)慣時(shí),這里最容易想當(dāng)然:已經(jīng)連上 app_db,所以表就在 app_db 里。更準(zhǔn)確的說法應(yīng)該是:當(dāng)前連接在 app_db,表對象屬于 app_db 里的 public schema。

也就是說,database 是更外層的連接邊界,schema 才是對象命名空間。后面寫 select * from t_schema_demo 時(shí),如果不帶 schema 前綴,數(shù)據(jù)庫會按當(dāng)前搜索路徑去找。

這里的 \dt 也能看出問題。它列出來的不只是表名,還有 schema。當(dāng)前結(jié)果里,已有的 t_ksql_conn_demo 和這次新建的 t_schema_demo 都在 public 下,owner 都是 app_user。這說明“誰創(chuàng)建”和“建在哪個(gè) schema”也是兩回事:當(dāng)前用戶是 app_user,對象 owner 是 app_user,但對象所在 schema 是 public。

寫 DDL 時(shí)最好先確認(rèn)這三件事。只知道“當(dāng)前連的是 app_db”還不夠,至少還要知道默認(rèn) schema 是什么。否則以后清理對象時(shí),可能會發(fā)現(xiàn)同一個(gè)庫里散著多個(gè) schema,表名也不一定唯一。

再建一個(gè) app_schema

接著創(chuàng)建一個(gè)新的 schema:

create schema app_schema authorization app_user;

再查當(dāng)前數(shù)據(jù)庫里關(guān)心的 schema:

select schema_name
from information_schema.schemata
where schema_name in ('public', 'app_schema');

結(jié)果里能看到 publicapp_schema。

app_schema 不是新數(shù)據(jù)庫,它只是 app_db 里的一個(gè)命名空間。authorization app_user 表示這個(gè) schema 歸 app_user 所有。

這一步不用先展開權(quán)限體系。先抓住一點(diǎn)就行:同一個(gè) database 里可以有多個(gè) schema。表名、視圖名、函數(shù)名這些對象名,都是在 schema 這一層組織的。

authorization app_user 也不是隨手加的裝飾。它讓 app_schema 這個(gè)命名空間歸 app_user 所有。后面在這個(gè) schema 下建表時(shí),邏輯就更接近日常開發(fā):普通用戶連接自己的數(shù)據(jù)庫,在自己的 schema 里放對象。完整權(quán)限還可以繼續(xù)細(xì)分,這里先把對象層級跑通。

在真實(shí)項(xiàng)目里,schema 常用來做隔離。比如一個(gè)庫里放業(yè)務(wù)表、報(bào)表表、中間表,或者遷移時(shí)先把舊系統(tǒng)對象放到單獨(dú) schema。這樣不需要每個(gè)模塊都拆成一個(gè)獨(dú)立數(shù)據(jù)庫,也能避免對象名互相撞在一起。

同一個(gè) database 里可以有同名表

現(xiàn)在顯式把表建到 app_schema 下:

create table app_schema.t_schema_demo(
  id int,
  name varchar(50)
);

insert into app_schema.t_schema_demo values (2, 'from app_schema');

再查 information_schema.tables

select table_schema, table_name
from information_schema.tables
where table_name = 't_schema_demo'
order by table_schema;

結(jié)果里出現(xiàn)了兩行:

app_schema | t_schema_demo
public     | t_schema_demo

這就是 schema 的作用。同一個(gè) app_db 里,public.t_schema_demoapp_schema.t_schema_demo 可以同時(shí)存在。它們名字一樣,但完整對象名不一樣。

這和 MySQL 里常見的 database.table 直覺不一樣。在 KingbaseES 里,寫到對象層面時(shí),更常見的是:

schema_name.table_name

如果只寫表名,數(shù)據(jù)庫不會憑空知道想查哪一個(gè) schema 下的表,它會按 search_path 的順序找。

同名表實(shí)驗(yàn)很適合用來打斷 MySQL 里的一個(gè)慣性:同一個(gè)“庫”里表名必須唯一。這里并不是同一個(gè) schema 里允許同名表,而是同一個(gè) database 里不同 schema 允許同名對象。完整對象名分別是:

public.t_schema_demo
app_schema.t_schema_demo

這兩個(gè)名字完整寫出來以后,就不沖突了。后面做 SQL 排查時(shí),如果只看到一個(gè)裸表名,不要馬上以為它指向唯一對象。先查對象歸屬,再看搜索路徑。

加上 schema 前綴,目標(biāo)就明確了

分別查詢兩張同名表:

select * from public.t_schema_demo;
select * from app_schema.t_schema_demo;

前一張表里是:

1 | from default schema

后一張表里是:

2 | from app_schema

加上 schema.table 前綴以后,查詢目標(biāo)很明確,不受當(dāng)前 search_path 順序影響。

平時(shí)寫業(yè)務(wù) SQL 時(shí),不一定每條都要帶 schema 前綴。很多項(xiàng)目會通過默認(rèn) schema 或連接參數(shù)把環(huán)境固定下來。但在排查問題、寫遷移腳本、做跨 schema 查詢時(shí),顯式寫出 schema 能少很多歧義。

有幾種場景最好直接寫全名:遷移腳本、初始化腳本、定時(shí)任務(wù)、跨 schema 查詢、臨時(shí)排查 SQL。這些 SQL 往往會在不同賬號、不同終端、不同工具里執(zhí)行,不能假設(shè)每次會話的 search_path 都一樣。寫成 app_schema.t_schema_demo 雖然長一點(diǎn),但現(xiàn)場更清楚。

尤其是多人共用測試庫時(shí),寫清 schema 能避免很多無意義的來回確認(rèn),也方便后面清理對象和復(fù)盤問題。

這也是遷移時(shí)很容易踩的點(diǎn)。MySQL 里從 db1.table1 改到 KingbaseES,不一定能機(jī)械改成 database.table。更常見的處理是:連接到目標(biāo) database,然后把對象放進(jìn)指定 schema,再用 schema.table 來訪問。具體怎么設(shè)計(jì),要看項(xiàng)目是否需要多 schema、是否要保留原庫名、是否要隔離臨時(shí)遷移對象。

search_path 會影響未加前綴的查詢

現(xiàn)在不帶 schema 前綴,直接查:

select * from t_schema_demo;

這條 SQL 查哪張表,取決于當(dāng)前 search_path

先把 app_schema 放到前面:

set search_path to app_schema, public;
show search_path;
select * from t_schema_demo;

返回的是 app_schema.t_schema_demo 里的數(shù)據(jù):

2 | from app_schema

再把 public 放到前面:

set search_path to public, app_schema;
show search_path;
select * from t_schema_demo;

返回變成 public.t_schema_demo 里的數(shù)據(jù):

1 | from default schema

這一步能解釋很多看起來很怪的問題。表存在,查詢也沒報(bào)錯(cuò),但結(jié)果不是預(yù)期那張表的數(shù)據(jù),原因可能不是 SQL 寫錯(cuò),而是未加前綴的表名被 search_path 解析到了另一個(gè) schema。

開發(fā)階段如果只有一個(gè) schema,問題不明顯。一旦出現(xiàn)多 schema、遷移臨時(shí) schema、按用戶隔離 schema,search_path 就會變得很重要。

這個(gè)實(shí)驗(yàn)里,兩次查詢的 SQL 都是:

select * from t_schema_demo;

SQL 文本沒有變化,結(jié)果卻變了。變化來自前面的:

set search_path to app_schema, public;
set search_path to public, app_schema;

這類問題在日志里也不好一眼看出來。只看業(yè)務(wù) SQL,會以為查的是同一張表;把當(dāng)時(shí)會話里的 search_path 補(bǔ)上,才能解釋結(jié)果為什么不同。所以排查“查錯(cuò)表”時(shí),show search_path; 應(yīng)該和 current_database()、current_user 一起看。

換成 system,再看同一個(gè) app_db

退出 app_user 后,換 system 連接同一個(gè)數(shù)據(jù)庫:

ksql -h 127.0.0.1 -p 54321 -U system -d app_db

再查當(dāng)前位置:

select current_database(), current_user, current_schema();

結(jié)果變成:

app_db | system | public

繼續(xù)查 t_schema_demo 的歸屬:

select table_schema, table_name
from information_schema.tables
where table_name = 't_schema_demo'
order by table_schema;

仍然能看到:

app_schema | t_schema_demo
public     | t_schema_demo

換用戶不等于換數(shù)據(jù)庫,也不等于把對象搬到別的 schema。system 只是換了當(dāng)前執(zhí)行 SQL 的身份,連接目標(biāo)仍然是 app_db,對象仍然在 publicapp_schema 下面。

這里先不展開授權(quán)。只看這一組結(jié)果已經(jīng)足夠說明:database、schema、user 不是一個(gè)概念。

換成 system 后,current_user 變了,但 current_database() 仍然是 app_db,對象歸屬也沒變。這能把 user 和 database 的邊界講清楚。用戶不是數(shù)據(jù)庫,數(shù)據(jù)庫也不是用戶。用戶只是當(dāng)前會話執(zhí)行 SQL 的身份,它會影響能不能看、能不能改、默認(rèn) schema 怎么解析,但不會因?yàn)閾Q用戶就把同一個(gè)數(shù)據(jù)庫里的對象改名或搬走。

這也是為什么不建議長期拿管理員用戶做日常實(shí)驗(yàn)。管理員用戶能看到更多東西,也能繞過一些權(quán)限限制。用它排查問題可以,拿它模擬普通應(yīng)用連接就不準(zhǔn)確。準(zhǔn)備 app_userapp_db,就是為了讓這些實(shí)驗(yàn)更接近日常開發(fā)賬號。

和 MySQL 的習(xí)慣對一下

如果從 MySQL 過來,可以先用下面這張對照表調(diào)整直覺:

MySQL 常見理解              KingbaseES 里要拆開看
database 常當(dāng)命名空間        database 是連接目標(biāo)
database.table              schema.table 更常見
use db                      ksql 里用 \c 切換連接數(shù)據(jù)庫
show tables                 \dt 或 information_schema.tables
當(dāng)前庫                       current_database()
當(dāng)前用戶                     current_user
默認(rèn) schema                  current_schema()
對象查找路徑                 search_path

這不是說 MySQL 的方式不好,而是兩套對象層級不一樣。MySQL 里很多時(shí)候看到“庫”,腦子里會自動(dòng)想到一組表;KingbaseES 這里連到 database 以后,還要繼續(xù)問:當(dāng)前 schema 是哪個(gè),表實(shí)際在哪個(gè) schema 下,當(dāng)前用戶有沒有權(quán)限訪問它。

前面實(shí)驗(yàn)里的幾個(gè)結(jié)果可以串起來看:

app_db                       當(dāng)前連接的 database
app_user / system            當(dāng)前執(zhí)行 SQL 的 user
public / app_schema          表所在的 schema
t_schema_demo                兩個(gè) schema 下都可以存在的表名
search_path                  不寫 schema 前綴時(shí)的查找順序

后面如果遇到“表不存在”“查到的不是預(yù)期數(shù)據(jù)”“換用戶以后看不到對象”,不要只盯著表名。先查 current_database()current_user、current_schema(),再看 search_path 和對象實(shí)際歸屬,很多問題會直接變清楚。

可以把排查順序固定下來:

select current_database(), current_user, current_schema();
show search_path;

select table_schema, table_name
from information_schema.tables
where table_name = '<表名>';

如果對象確實(shí)存在,再看權(quán)限;如果對象在另一個(gè) schema,先決定是改 SQL 加前綴,還是調(diào)整當(dāng)前會話的 search_path。不要一上來就懷疑表丟了,也不要直接重建同名表。schema 沒看清時(shí),重建對象反而可能把現(xiàn)場弄得更亂。

比如應(yīng)用報(bào)“表不存在”,先不要急著執(zhí)行 create table。如果表在 app_schema,而連接進(jìn)來以后默認(rèn)搜索的是 public,裸寫 select * from t_schema_demo 就可能找不到目標(biāo)對象。這個(gè)時(shí)候有兩種處理方式:SQL 里寫成 app_schema.t_schema_demo,或者在連接會話里把 app_schema 放進(jìn) search_path。兩種方式都能解決問題,但含義不一樣。前者目標(biāo)最明確,后者更依賴會話配置。

再比如查出來的數(shù)據(jù)不對,也不一定是數(shù)據(jù)被改壞了。同名表同時(shí)存在時(shí),public.t_schema_demoapp_schema.t_schema_demo 都能正常查詢,只是數(shù)據(jù)來源不同。SQL 不帶 schema 前綴時(shí),結(jié)果跟著 search_path 走。這個(gè)問題在測試庫里不顯眼,到了遷移驗(yàn)證、報(bào)表庫、臨時(shí)表整理時(shí)就會很煩。

到此這篇關(guān)于MySQL和KingbaseES中連接、對象命名空間及用戶權(quán)限的區(qū)別的文章就介紹到這了,更多相關(guān)MySQL和KingbaseES的區(qū)別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MYSQL 無法識別中文的永久解決方法

    MYSQL 無法識別中文的永久解決方法

    多數(shù)情況下,mysql在剛剛安裝時(shí)是不支持中文的,這是由于編碼的問題,那么如何解決這個(gè)方法,本文我們就來詳細(xì)的了解一下
    2021-06-06
  • Mysql Error 1826:Duplicate foreign key constraint錯(cuò)誤問題及解決

    Mysql Error 1826:Duplicate foreign key&n

    MySQL1826錯(cuò)誤是由于在創(chuàng)建表時(shí),外鍵索引名重復(fù)導(dǎo)致的,解決辦法是在創(chuàng)建外鍵時(shí)指定不同的索引名,或修改ForeignKeyName,此問題需注意索引和外鍵名稱的唯一性
    2026-05-05
  • MySQL 4G內(nèi)存服務(wù)器配置優(yōu)化

    MySQL 4G內(nèi)存服務(wù)器配置優(yōu)化

    MySQL對于web架構(gòu)性能的影響最大,也是關(guān)鍵的核心部分。下面我們了解一下MySQL優(yōu)化的一些基礎(chǔ),MySQL自身(my.cnf)的優(yōu)化
    2017-07-07
  • MySQL5.6的zip包安裝教程詳解

    MySQL5.6的zip包安裝教程詳解

    這篇文章主要介紹了MySQL5.6的zip包安裝教程,需要的朋友可以參考下
    2018-11-11
  • Mysql之如何實(shí)現(xiàn)全外連接

    Mysql之如何實(shí)現(xiàn)全外連接

    這篇文章主要介紹了Mysql之如何實(shí)現(xiàn)全外連接問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • MySQL高頻面試題完整版(由淺到深,面試必背)

    MySQL高頻面試題完整版(由淺到深,面試必背)

    MySQL作為目前最廣泛使用的關(guān)系型數(shù)據(jù)庫之一,許多互聯(lián)網(wǎng)大廠在招聘時(shí)都會重點(diǎn)考察應(yīng)聘者對數(shù)據(jù)庫相關(guān)知識的掌握程度,這篇文章主要介紹了MySQL高頻面試題的相關(guān)資料,需要的朋友可以參考下
    2026-05-05
  • MySQL Workbench工具導(dǎo)出導(dǎo)入數(shù)據(jù)庫方式

    MySQL Workbench工具導(dǎo)出導(dǎo)入數(shù)據(jù)庫方式

    這篇文章主要介紹了MySQL Workbench工具導(dǎo)出導(dǎo)入數(shù)據(jù)庫方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-05-05
  • MySQL數(shù)據(jù)庫10秒內(nèi)插入百萬條數(shù)據(jù)的實(shí)現(xiàn)

    MySQL數(shù)據(jù)庫10秒內(nèi)插入百萬條數(shù)據(jù)的實(shí)現(xiàn)

    假設(shè)現(xiàn)在我們要向mysql插入500萬條數(shù)據(jù),如何實(shí)現(xiàn)高效快速的插入進(jìn)去?本文就詳細(xì)的介紹一下,感興趣的可以了解一下
    2021-10-10
  • 集群rpm安裝MySQL步驟詳解

    集群rpm安裝MySQL步驟詳解

    在本篇文章里小編給大家整理的是一篇關(guān)于集群rpm安裝MySQL步驟內(nèi)容,需要的朋友們可以參考學(xué)習(xí)下。
    2020-01-01
  • MySQL source命令的使用簡介

    MySQL source命令的使用簡介

    這篇文章主要介紹了MySQL source命令的使用簡介,幫助大家更好的理解和學(xué)習(xí)使用MySQL,感興趣的朋友可以了解下
    2021-03-03

最新評論

江孜县| 闸北区| 伊宁市| 兴安县| 上高县| 京山县| 叶城县| 新昌县| 莫力| 宜春市| 石城县| 宁南县| 夏河县| 固安县| 瓮安县| 河北区| 图片| 湾仔区| 义乌市| 云安县| 崇明县| 平谷区| 襄樊市| 噶尔县| 益阳市| 海林市| 务川| 兴宁市| 漠河县| 和政县| 锦屏县| 青铜峡市| 九江县| 池州市| 长宁区| 类乌齐县| 伊吾县| 京山县| 镇安县| 水富县| 晴隆县|