sql >> Database >  >> RDS >> PostgreSQL

Hoe beïnvloedt het zoekpad de resolutie van de ID en het huidige schema?

Wat is het schema-zoekpad search_path ?

De handleiding:

[...] tabellen worden vaak aangeduid met ongekwalificeerde namen, die alleen uit de tabelnaam bestaan. Het systeem bepaalt welke tabel wordt bedoeld door een zoekpad te volgen, dat is een lijst met schema's om in te kijken .

Vetgedrukte nadruk van mij. Dit verklaart identificatieresolutie .

Het “huidige schema” (of "standaardschema") is, per documentatie:

Het eerste schema genoemd in het zoekpad heet het huidigeschema . Behalve dat het het eerste schema is waarnaar wordt gezocht, is het ook het schema waarin nieuwe tabellen worden gemaakt als de CREATE TABLE commando specificeert geen schemanaam.

Vetgedrukte nadruk van mij. De systeemschema's pg_temp (schema voor tijdelijke objecten van de huidige sessie) en pg_catalog maken automatisch deel uit van het zoekpad en worden eerst gezocht , in deze volgorde. De handleiding:

pg_catalog is altijd effectief onderdeel van het zoekpad. Als het niet expliciet wordt genoemd in het pad, wordt er impliciet naar gezocht voor zoeken in de schema's van het pad. Dit zorgt ervoor dat ingebouwde namen altijd vindbaar zijn. U kunt echter expliciet pg_catalog . plaatsen aan het einde van uw zoekpad als u liever door de gebruiker gedefinieerde namen de ingebouwde namen overschrijft.

Vetgedrukte nadruk volgens origineel. En pg_temp komt daarvoor, tenzij het in een andere positie wordt gezet.

Hoe stel je het in?

Er zijn verschillende manieren om de runtime-variabele search_path in te stellen .

  1. Stel een cluster in -brede standaard voor alle rollen in alle databases in postgresql.conf (en herladen). Voorzichtig daarmee!

    search_path = 'blarg,public'
    

    De standaardwaarde voor deze instelling is:

    search_path = "$user",public
    

    Het eerste element geeft aan dat een schema met dezelfde naam als de huidige gebruiker moet worden doorzocht. Als zo'n schema niet bestaat, wordt de invoer genegeerd.

  2. Stel het in als standaard voor één database :

    ALTER DATABASE test SET search_path = blarg,public;
    
  3. Stel het in als standaard voor de rol waarmee u verbinding maakt (effectief clusterbreed):

    ALTER ROLE foo SET search_path = blarg,public;
    
  4. Of zelfs (vaak het beste!) als standaard voor een rol in een database :

    ALTER ROLE foo IN DATABASE test SET search_path = blarg,public;
    
  5. Schrijf de opdracht bovenaan je script. Of voer het uit in uw DB sessie :

    SET search_path = blarg,public;
    
  6. Stel een specifiek search_path in voor de scope van een functie (om te worden beschermd tegen kwaadwillende gebruikers met voldoende privileges). Lees over het schrijven van SECURITY DEFINER Functioneert veilig in de handleiding.

CREATE FUNCTION foo() RETURNS void AS
$func$
BEGIN
   -- do stuff
END
$func$ LANGUAGE plpgsql SECURITY DEFINER
       SET search_path=blarg,public,pg_temp;

Een hoger nummer in mijn lijst is belangrijker dan een lager nummer.
De handleiding heeft nog meer manieren , zoals het instellen van omgevingsvariabelen of het gebruik van opdrachtregelopties.

Om de huidige instelling te zien:

SHOW search_path;

Om het te resetten:

RESET search_path;

De handleiding:

De standaardwaarde wordt gedefinieerd als de waarde die de parameter zou hebben gehad, indien geen SET was er ooit voor uitgegeven in de huidige sessie.



  1. Evenementen en discussies in .NET

  2. Stel de tekenset en sortering van een database in MariaDB in

  3. Een Unix-tijdstempel converteren naar een datum/tijd-waarde in SQL Server

  4. Tips voor het leveren van MySQL-databaseprestaties - deel twee