除了public和用户创建的模式如lt_abc之外,在lightdb中,每个数据库都包含一个pg_catalog和lt_catalog模式,它包含系统表和所有内置数据类型、函数、操作符。lt_catalog和pg_catalog总是搜索路径search_path中的一部分。如果它没有明确出现在路径中,那么它隐含地在所有路径之前搜索。这样就保证了内置名字总是可以被搜索。不过,你可以明确地把pg_catalog放在搜索路径之后,如果你想使用用户自定义的名字覆盖内置名字的话,例如oracle标识符覆盖原生PG标识符。
另外,每个数据库中还包含information_schema,和mysql一样,因为它是SQL规范的一部分,不过它默认不在search_path搜索目录。
考虑到逻辑备份和恢复,一般不建议用户表创建在public schema下,而是创建一个和用户名相同的schema,这样备份恢复可以指定schema,更加的方便。
关于临时模式pg_temp
在执行DDL如create table过程中,pg内核中有一段逻辑是判断对象所属的命名空间是否为临时模式,如下:
if (newRelation->schemaname)
{
/* check for pg_temp alias */
if (strcmp(newRelation->schemaname, "pg_temp") == 0)
{
/* Initialize temp namespace */
AccessTempTableNamespace(false);
return myTempNamespace;
}
/* use exact schema given */
namespaceId = get_namespace_oid(newRelation->schemaname, false);
/* we do not check for USAGE rights here! */
}
else if (newRelation->relpersistence == RELPERSISTENCE_TEMP)
{
/* Initialize temp namespace */
AccessTempTableNamespace(false);
return myTempNamespace;
}
但是在pg官方文档包括internals章节中,从来没有提到任何pg_temp和临时模式直接相关的信息,仅仅在http://www.light-pg.com/docs/lightdb/13.3-22.2/runtime-config-client.html。如下:
Likewise, the current session's temporary-table schema, pg_temp_nnn, is always searched if it exists. It can be explicitly listed in the path by using the alias pg_temp. If it is not listed in the path then it is searched first (even before pg_catalog). However, the temporary schema is only searched for relation (table, view, sequence, etc) and data type names. It is never searched for function or operator names.
从源码可知,临时schema主要用于临时表的存储。
void
RangeVarAdjustRelationPersistence(RangeVar *newRelation, Oid nspid)
{
switch (newRelation->relpersistence)
{
case RELPERSISTENCE_TEMP:
if (!isTempOrTempToastNamespace(nspid))
{
if (isAnyTempNamespace(nspid))
ereport(ERROR,
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
errmsg("cannot create relations in temporary schemas of other sessions")));
else
ereport(ERROR,
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
errmsg("cannot create temporary relation in non-temporary schema")));
}
break;
case RELPERSISTENCE_PERMANENT:
if (isTempOrTempToastNamespace(nspid))
newRelation->relpersistence = RELPERSISTENCE_TEMP;
else if (isAnyTempNamespace(nspid))
ereport(ERROR,
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
errmsg("cannot create relations in temporary schemas of other sessions")));
break;
default:
if (isAnyTempNamespace(nspid))
ereport(ERROR,
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
errmsg("only temporary relations may be created in temporary schemas")));
}
}
实际上临时模式的名称为pg_temp_N,n为数字,它本质上无常规的模式无区别,仅仅通过名称标识。但是dba运维的时候需要记得这个事情,不要假设它是用户创建的随意schema,否则可能会导致有auto vacuum无法清理的野对象,