CREATE_SCHEMA(7)
๐ CREATE_SCHEMA ๐
okay bestie, welcome to the PostgreSQL 18.6 Documentation glow-up of CREATE_SCHEMA(7) โ this is the page that teaches you how to make a whole new schema, which is basically a lil namespace closet for all your tables, types, functions and operators. let's get into it โจ
๐ธ NAME ๐ธ
CREATE_SCHEMA โ define a new schema, no cap ๐ซถ
โจ SYNOPSIS โจ
CREATE SCHEMA schema_name [ AUTHORIZATION role_specification ] [ schema_element [ ... ] ]
CREATE SCHEMA AUTHORIZATION role_specification [ schema_element [ ... ] ]
CREATE SCHEMA IF NOT EXISTS schema_name [ AUTHORIZATION role_specification ]
CREATE SCHEMA IF NOT EXISTS AUTHORIZATION role_specification
and role_specification can be any of these, periodt:
user_name
| CURRENT_ROLE
| CURRENT_USER
| SESSION_USER
๐ฆ DESCRIPTION ๐ฆ
CREATE SCHEMA slides a brand new schema into your current database, like it's joining the group chat. the schema name has to be different from every existing schema name in that same database โ no duplicates allowed, iykyk ๐
a schema is essentially a namespace: it holds named objects โ tables, data types, functions, and operators โ whose names are allowed to be the same as objects living in other schemas. to reach a named object you either โqualifyโ its name by sticking the schema name on the front as a prefix, or you set a search path that includes the schema(s) you want. and when a CREATE command gives an unqualified object name? it makes that object in the current schema โ that's the one sitting at the very front of the search path, which you can figure out with the function current_schema. main character energy fr fr ๐
optionally, CREATE SCHEMA can also carry subcommands that create objects inside the brand new schema. those subcommands are basically treated the same as if you'd issued them as separate commands right after creating the schema โ EXCEPT that if the AUTHORIZATION clause is there, every single created object gets owned by that user ๐
๐ PARAMETERS ๐
schema_nameโ the name of the schema you're creating. if you skip it, theuser_namegets used as the schema name instead. it cannot start withpg_, because names like that are reserved for system schemas. ๐user_nameโ the role name of whoever is gonna own this new schema. if you leave it out, it defaults to the user running the command. and if you wanna make a schema owned by another role, you gotta be able toSET ROLEto that role first. slay responsibly ๐schema_elementโ an SQL statement that defines an object to be created inside the schema. rn, onlyCREATE TABLE,CREATE VIEW,CREATE INDEX,CREATE SEQUENCE,CREATE TRIGGERandGRANTare accepted as clauses insideCREATE SCHEMA. any other kinds of objects? you'll have to create those in separate commands after the schema exists. ๐ซถIF NOT EXISTSโ do nothing (well, issue a notice) if a schema with that same name already exists. you can't includeschema_elementsubcommands when you use this option. ๐
โญ NOTES โญ
to create a schema, the user invoking it needs the CREATE privilege on the current database. (and obviously, superusers just bypass that check entirely, as they do ๐)
๐ EXAMPLES ๐
make a schema:
CREATE SCHEMA myschema;
make a schema for user joe โ and guess what, the schema is also named joe:
CREATE SCHEMA AUTHORIZATION joe;
make a schema named test owned by user joe, unless a schema named test already exists. (doesn't matter one bit whether joe owns that pre-existing schema, we're not asking questions ๐)
CREATE SCHEMA IF NOT EXISTS test AUTHORIZATION joe;
make a schema AND build a table and a view inside it:
CREATE SCHEMA hollywood
CREATE TABLE films (title text, release date, awards text[])
CREATE VIEW winners AS
SELECT title, release FROM films WHERE awards IS NOT NULL;
heads up bestie: notice that the individual subcommands do not end with semicolons. not a single one. ๐ญ
and here's the equivalent way to get the exact same result:
CREATE SCHEMA hollywood;
CREATE TABLE hollywood.films (title text, release date, awards text[]);
CREATE VIEW hollywood.winners AS
SELECT title, release FROM hollywood.films WHERE awards IS NOT NULL;
๐ COMPATIBILITY ๐
the SQL standard lets CREATE SCHEMA take a DEFAULT CHARACTER SET clause, and also allows more subcommand types than PostgreSQL currently accepts. we're built different, ok ๐ง
the SQL standard says the subcommands inside CREATE SCHEMA can show up in any order. the present PostgreSQL implementation does not handle all cases of forward references in subcommands โ so sometimes you might have to reorder the subcommands just to dodge those forward references. annoying but true ๐
per the SQL standard, the owner of a schema always owns every object inside it. PostgreSQL, though, lets schemas contain objects owned by users other than the schema owner. this can only happen if the schema owner grants the CREATE privilege on their schema to somebody else, or if a superuser decides to create objects in it. icon behaviour tbh ๐
the IF NOT EXISTS option is a PostgreSQL extension. ๐
๐ฅ SEE ALSO ๐ฅ
ALTER SCHEMA(ALTER_SCHEMA(7))DROP SCHEMA(DROP_SCHEMA(7))
and that's the whole page bestie!! ๐ this was CREATE SCHEMA(7) from PostgreSQL 18.6, dated 2026 โ go forth and namespace your little heart out, you absolute legend ๐โจ๐ฆ๐๐
๐ฆ where this page comes from
- alpine 3.23: postgresql18-doc 18.6-r0 ยท PostgreSQL
- alpine 3.24: postgresql18-doc 18.6-r0 ยท PostgreSQL
- arch rolling: postgresql 18.6-4 ยท PostgreSQL
- fedora 43: postgresql 18.6-1.fc43 ยท PostgreSQL
- fedora 43: postgresql 18.6-1.fc43 ยท PostgreSQL
- fedora 44: postgresql 18.6-1.fc44 ยท PostgreSQL
- fedora 44: postgresql 18.6-1.fc44 ยท PostgreSQL
- nixos 26.05: postgresql 18.6
- ubuntu resolute: postgresql-client-18 18.6-0ubuntu0.26.04.1 ยท PostgreSQL
- ubuntu stonking: postgresql-client-18 18.6-3build2 ยท PostgreSQL
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms