-- 0005 · 스키마를 해체하고 이름으로 소속을 말한다 -- -- ★ 왜 (2026-09-09) -- 스키마를 나누는 이유는 셋뿐이다 — ① 같은 이름을 여러 번 쓰려고 ② 권한을 덩어리로 주려고 -- ③ 읽는 사람에게 경계를 보여주려고. 이 프로젝트에선 ①②가 성립하지 않는다: -- · `web4ai_db` 는 이 제품 전용 database 다. 다른 프로젝트는 다른 database 에 있고, -- 19개 테이블 이름이 전부 다르다 — 충돌할 상대가 애초에 없다. -- · 접속 계정이 하나다. 스키마별 GRANT 를 준 적이 없고, 실제 권한 분리는 DB 밖에서 -- 포트로 한다(솔루션 9800 / 어드민 9801, ADMIN_API_BIND=127.0.0.1). -- ③만 남는데, 그 값을 치르는 방식이 틀렸다: -- · 19개 중 9개가 스키마 이름을 다시 말한다(place.places · fact.facts · site.sites · -- local.local_contents · job.jobs …). 폴더 이름이 파일 이름에 이미 들어 있으면 -- 그 폴더는 정보를 더하지 못한다. -- · **결정적으로, 경계가 조인 방향과 반대다.** `places.place_id` 를 참조하는 테이블이 -- 11개인데 그중 `place` 스키마 안에 있는 건 **하나도 없다**. 관계를 잇는 컬럼이 -- 매번 경계를 넘는다면 그건 경계가 아니다. 특히 업장↔지역 관계 테이블은 -- 존재 자체가 두 스키마를 잇는 것이라 어디에 둬도 틀린다. -- -- 그래서 스키마를 없애고 **접두어가 소속을 말한다.** -- place_* 한 업장의 것 · site_* 한 사이트의 것 · users/jobs 아무에게도 안 속함 -- area_contents 만 접두어가 없다 — **그게 공유물이라는 표시다.** -- 이 규칙이 서면 오늘 같은 복제 사고는 이름만 봐도 걸린다(place_ 붙은 테이블에 축제가 -- 들어가 있으면 그 자체로 틀린 것이다). -- -- ★ 데이터는 옮기지 않는다. RENAME 뿐이라 잃는 행이 없다. -- ── 사람 · 큐 (아무에게도 안 속한다) ────────────────────────────────────── ALTER TABLE IF EXISTS company.users SET SCHEMA public; ALTER TABLE IF EXISTS job.jobs SET SCHEMA public; -- ── 업장 ──────────────────────────────────────────────────────────────── ALTER TABLE IF EXISTS place.places SET SCHEMA public; ALTER TABLE IF EXISTS place.place_links SET SCHEMA public; ALTER TABLE IF EXISTS place.units SET SCHEMA public; ALTER TABLE IF EXISTS place.media SET SCHEMA public; ALTER TABLE IF EXISTS fact.facts SET SCHEMA public; ALTER TABLE IF EXISTS fact.faqs SET SCHEMA public; -- 이름이 무엇에 속하는지, 그리고 무엇을 담는지 말하게 한다. ALTER TABLE IF EXISTS public.place_links RENAME TO place_channels; -- 네이버·야놀자 등 채널 ALTER TABLE IF EXISTS public.units RENAME TO place_units; -- 객실·메뉴·프로그램 ALTER TABLE IF EXISTS public.media RENAME TO place_photos; -- 실제로 사진만 담는다 ALTER TABLE IF EXISTS public.facts RENAME TO place_facts; ALTER TABLE IF EXISTS public.faqs RENAME TO place_faqs; -- ── 지역 (여럿이 나눠 쓴다) ────────────────────────────────────────────── ALTER TABLE IF EXISTS local.local_contents SET SCHEMA public; ALTER TABLE IF EXISTS local.place_contents SET SCHEMA public; -- 접두어 없는 유일한 테이블. 공유물이라는 표시다. ALTER TABLE IF EXISTS public.local_contents RENAME TO area_contents; -- 값이 아니라 **관계**다 — 이름이 그걸 말해야 한다. ALTER TABLE IF EXISTS public.place_contents RENAME TO place_area_refs; -- ── 사이트 ────────────────────────────────────────────────────────────── ALTER TABLE IF EXISTS site.sites SET SCHEMA public; ALTER TABLE IF EXISTS site.site_contents SET SCHEMA public; ALTER TABLE IF EXISTS site.site_versions SET SCHEMA public; ALTER TABLE IF EXISTS site.publish_logs SET SCHEMA public; -- 섹션의 '내용'이다. site_contents 는 무엇의 콘텐츠인지 말하지 않는다. ALTER TABLE IF EXISTS public.site_contents RENAME TO site_sections; ALTER TABLE IF EXISTS public.publish_logs RENAME TO site_publish_logs; -- ── 아직 남기는 것 ────────────────────────────────────────────────────── -- 빈 테이블(place_aliases · routes · nearby_links · ai_check_results)과 이관 잔재 -- (place_contents_legacy)는 0006 에서 판단한다. 한 파일에 두 가지 일을 넣지 않는다. ALTER TABLE IF EXISTS place.place_aliases SET SCHEMA public; ALTER TABLE IF EXISTS local.routes SET SCHEMA public; ALTER TABLE IF EXISTS local.nearby_links SET SCHEMA public; ALTER TABLE IF EXISTS site.ai_check_results SET SCHEMA public; ALTER TABLE IF EXISTS local.place_contents_legacy SET SCHEMA public; ALTER TABLE IF EXISTS public.routes RENAME TO place_routes; ALTER TABLE IF EXISTS public.place_aliases RENAME TO place_names; -- ai_check_results 는 place_id 가 키다 — 사이트가 아니라 **업장**이 AI 검색에 나오는지를 -- 재는 것이라, 사이트를 안 만들어도 잴 수 있다. site_ 가 아니라 place_ 다. ALTER TABLE IF EXISTS public.ai_check_results RENAME TO place_ai_checks; -- ── 빈 스키마 정리 ────────────────────────────────────────────────────── -- ★ CASCADE 를 쓰지 않는다. 옮기다 빠뜨린 테이블이 있으면 여기서 실패해야 한다 — -- CASCADE 면 그 테이블이 조용히 함께 지워진다. DROP SCHEMA IF EXISTS company RESTRICT; DROP SCHEMA IF EXISTS place RESTRICT; DROP SCHEMA IF EXISTS fact RESTRICT; DROP SCHEMA IF EXISTS local RESTRICT; DROP SCHEMA IF EXISTS site RESTRICT; DROP SCHEMA IF EXISTS job RESTRICT;