TL; DR: Nowi użytkownicy mogą tworzyć tabele w publicschemacie, ponieważ ludzie narzekali, że było to zbyt trudne, gdy nie mogli.
Jeśli nie podoba Ci się wartość domyślna, prawdopodobnie powinieneś utworzyć nową bazę danych szablonów z pożądaną konfiguracją początkową. Na przykład możesz:
DROP SCHEMA public;
lub
REVOKE ALL ON SCHEMA public FROM public;
GRANT USAGE ON SCHEMA public TO public;
w twoim szablonie.
Jeśli chcesz, aby publicużytkownik nie miał żadnych uprawnień do bazy danych, powinieneś dodatkowo:
REVOKE ALL ON DATABASE mydbname FROM public;
GRANT CONNECT ON DATABASE mydbname TO public;
aby publicużytkownik nie mógł tworzyć schematów ani używać tabel tymczasowych.
Osobiście, gdybym to projektował, dałbym użytkownikom TEMPdomyślnie prawo do bazy danych, ale nie CREATE(schematy w bazie danych) lub CREATE(tabele w publicschemacie). Zarezerwowałbym je dla właściciela.
Są to jednak wybory, których dokonano dawno temu i teraz bardzo trudno je zmienić.
W tej chwili pojawiają się regularne skargi, że zbyt trudno jest zacząć korzystać z PostgreSQL, ponieważ musisz utworzyć konto użytkownika i często chcesz również utworzyć bazę danych. Dlaczego po prostu nie utworzymy ich automatycznie i domyślnie „zaufamy” jako trybowi uwierzytelnienia, aby było to łatwe? Dlaczego postgresużytkownik domyślnie nie ma hasła postgres? Dlaczego po prostu nie tworzymy automatycznie użytkowników, jeśli istnieją w systemie operacyjnym? itp.
Istnieją nowe problemy z użytecznością dla nowych użytkowników - w szczególności większość ludzi nie ma pojęcia, czym peerjest uwierzytelnianie lub dlaczego właśnie uruchomienie psqlpo zainstalowaniu PostgreSQL mówi im, że nie ma użytkownika o nazwie, pod którą się zalogowali.
Jest to również bałagan, który pg_hba.confjest plikiem konfiguracyjnym, ale użytkownicy są tworzeni na poziomie SQL. Ten podział dezorientuje użytkowników.
Jednak wiele rzeczy to kompromisy między bezpiecznymi domyślnymi i łatwymi domyślnymi, w których projekt nigdy nie sprawi, że wszyscy będą zadowoleni.
revoke create on database [databasename] from [username];i DB jest teraz naprawdę tylko do odczytu dla [nazwa użytkownika]. Dobrze? Wrócę do tej odpowiedzi ponownie, gdy przeczytam dobrą książkę Postgres :)