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, the user_name gets used as the schema name instead. it cannot start with pg_, 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 to SET ROLE to that role first. slay responsibly ๐Ÿ’…
  • schema_element โ€” an SQL statement that defines an object to be created inside the schema. rn, only CREATE TABLE, CREATE VIEW, CREATE INDEX, CREATE SEQUENCE, CREATE TRIGGER and GRANT are accepted as clauses inside CREATE 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 include schema_element subcommands 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 ๐Ÿ”ฅ


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 ๐ŸŽ€โœจ๐Ÿฆ‹๐Ÿ‘‘๐Ÿ’