kibioctet

JvArchive schéma v3

Mar 16th, 2026
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- ============================================================
  2. -- JvArchive - PostgreSQL 16+
  3. -- Schéma recommandé - version psql/\i compatible
  4. -- ============================================================
  5.  
  6. \set ON_ERROR_STOP on
  7.  
  8. -- ------------------------------------------------------------
  9. -- Réglages de session pour bulk load
  10. -- ------------------------------------------------------------
  11. SET client_encoding = 'UTF8';
  12. SET DateStyle = 'ISO, YMD';
  13. SET TimeZone = 'UTC';
  14. SET synchronous_commit = OFF;
  15. SET maintenance_work_mem = '4GB';
  16. SET work_mem = '64MB';
  17. SET temp_buffers = '256MB';
  18. SET statement_timeout = 0;
  19. SET lock_timeout = 0;
  20. SET idle_in_transaction_session_timeout = 0;
  21. SET max_parallel_maintenance_workers = 4;
  22.  
  23. -- ------------------------------------------------------------
  24. -- Extensions
  25. -- ------------------------------------------------------------
  26. CREATE EXTENSION IF NOT EXISTS pg_trgm;
  27.  
  28. -- ------------------------------------------------------------
  29. -- Reset
  30. -- ------------------------------------------------------------
  31. DROP TABLE IF EXISTS messages CASCADE;
  32. DROP TABLE IF EXISTS topics CASCADE;
  33. DROP TABLE IF EXISTS auteurs CASCADE;
  34.  
  35. -- ------------------------------------------------------------
  36. -- Tables métier
  37. -- ------------------------------------------------------------
  38. CREATE TABLE auteurs (
  39.     id      bigint NOT NULL,
  40.     pseudo  text   NOT NULL,
  41.     avatar  text   NULL
  42. );
  43.  
  44. CREATE TABLE topics (
  45.     id                               bigint      NOT NULL,
  46.     titre                            text        NOT NULL,
  47.     nb_messages                      integer     NOT NULL,
  48.     date_creation                    timestamptz NOT NULL,
  49.     date_suppression                 timestamptz NULL,
  50.     restaure                         boolean     NOT NULL DEFAULT false,
  51.     delete_by_modo                   boolean     NOT NULL DEFAULT false,
  52.     auteur_id                        bigint      NULL,
  53.     date_dernier_message             timestamptz NOT NULL,
  54.     date_dernier_message_enregistre  timestamptz NULL,
  55.     nb_messages_enregistre           integer     NULL,
  56.     CONSTRAINT topics_nb_messages_chk
  57.         CHECK (nb_messages >= 0),
  58.     CONSTRAINT topics_nb_messages_enregistre_chk
  59.         CHECK (
  60.             nb_messages_enregistre IS NULL
  61.             OR nb_messages_enregistre >= 0
  62.         )
  63. );
  64.  
  65. CREATE TABLE messages (
  66.     topic_id  bigint      NOT NULL,
  67.     id        bigint      NOT NULL,
  68.     auteur_id bigint      NULL,
  69.     date_post timestamptz NOT NULL,
  70.     texte     text        NOT NULL
  71. ) PARTITION BY HASH (topic_id);
  72.  
  73. -- ------------------------------------------------------------
  74. -- Partitions HASH de messages
  75. -- ------------------------------------------------------------
  76. DO $$
  77. DECLARE
  78.     v_partitions integer := 32;
  79.     i integer;
  80. BEGIN
  81.     FOR i IN 0..v_partitions - 1 LOOP
  82.         EXECUTE format(
  83.             'CREATE TABLE messages_p%s PARTITION OF messages
  84.             FOR VALUES WITH (MODULUS %s, REMAINDER %s);',
  85.             lpad(i::text, 2, '0'),
  86.             v_partitions,
  87.             i
  88.         );
  89.     END LOOP;
  90. END
  91. $$;
  92.  
  93. -- ------------------------------------------------------------
  94. -- Import AUTEURS
  95. -- ------------------------------------------------------------
  96. \echo Import auteurs depuis auteurs.csv
  97. \copy auteurs (id, pseudo, avatar) FROM 'auteurs.csv' WITH (FORMAT csv, HEADER true)
  98.  
  99. -- ------------------------------------------------------------
  100. -- Import TOPICS via staging 100% texte
  101. -- ------------------------------------------------------------
  102. DROP TABLE IF EXISTS topics_stage;
  103.  
  104. CREATE TEMP TABLE topics_stage (
  105.     id                               text,
  106.     titre                            text,
  107.     nb_messages                      text,
  108.     date_creation                    text,
  109.     date_suppression                 text,
  110.     restaure                         text,
  111.     delete_by_modo                   text,
  112.     auteur_id                        text,
  113.     date_dernier_message             text,
  114.     date_dernier_message_enregistre  text,
  115.     nb_messages_enregistre           text
  116. );
  117.  
  118. \echo Import topics_stage depuis topics.csv
  119. \copy topics_stage (id, titre, nb_messages, date_creation, date_suppression, restaure, delete_by_modo, auteur_id, date_dernier_message, date_dernier_message_enregistre, nb_messages_enregistre) FROM 'topics.csv' WITH (FORMAT csv, HEADER true)
  120.  
  121. INSERT INTO topics (
  122.     id,
  123.     titre,
  124.     nb_messages,
  125.     date_creation,
  126.     date_suppression,
  127.     restaure,
  128.     delete_by_modo,
  129.     auteur_id,
  130.     date_dernier_message,
  131.     date_dernier_message_enregistre,
  132.     nb_messages_enregistre
  133. )
  134. WITH normalized AS (
  135.     SELECT
  136.         NULLIF(btrim(id), '')::bigint AS id,
  137.         titre,
  138.         COALESCE(NULLIF(btrim(nb_messages), '')::integer, 0) AS nb_messages,
  139.  
  140.         NULLIF(btrim(date_creation), '')::timestamptz AS date_creation_ts,
  141.         NULLIF(btrim(date_suppression), '')::timestamptz AS date_suppression_ts,
  142.         NULLIF(btrim(date_dernier_message), '')::timestamptz AS date_dernier_message_ts,
  143.         NULLIF(btrim(date_dernier_message_enregistre), '')::timestamptz AS date_dernier_message_enregistre_ts,
  144.  
  145.         CASE
  146.             WHEN restaure IS NULL OR btrim(restaure) = '' THEN false
  147.             WHEN lower(btrim(restaure)) IN ('true', 't', 'yes', 'y', 'on', '1') THEN true
  148.             WHEN lower(btrim(restaure)) IN ('false', 'f', 'no', 'n', 'off', '0') THEN false
  149.             WHEN btrim(restaure) ~ '^[0-9]+$' THEN (btrim(restaure)::integer <> 0)
  150.             ELSE false
  151.         END AS restaure_bool,
  152.  
  153.         CASE
  154.             WHEN delete_by_modo IS NULL OR btrim(delete_by_modo) = '' THEN false
  155.             WHEN lower(btrim(delete_by_modo)) IN ('true', 't', 'yes', 'y', 'on', '1') THEN true
  156.             WHEN lower(btrim(delete_by_modo)) IN ('false', 'f', 'no', 'n', 'off', '0') THEN false
  157.             WHEN btrim(delete_by_modo) ~ '^[0-9]+$' THEN (btrim(delete_by_modo)::integer <> 0)
  158.             ELSE false
  159.         END AS delete_by_modo_bool,
  160.  
  161.         NULLIF(btrim(auteur_id), '')::bigint AS auteur_id,
  162.         NULLIF(btrim(nb_messages_enregistre), '')::integer AS nb_messages_enregistre
  163.     FROM topics_stage
  164. )
  165. SELECT
  166.     id,
  167.     titre,
  168.     nb_messages,
  169.     COALESCE(
  170.         date_creation_ts,
  171.         date_dernier_message_ts,
  172.         date_dernier_message_enregistre_ts,
  173.         date_suppression_ts
  174.     ) AS date_creation,
  175.     date_suppression_ts,
  176.     restaure_bool,
  177.     delete_by_modo_bool,
  178.     auteur_id,
  179.     COALESCE(
  180.         date_dernier_message_ts,
  181.         date_dernier_message_enregistre_ts,
  182.         date_creation_ts,
  183.         date_suppression_ts
  184.     ) AS date_dernier_message,
  185.     date_dernier_message_enregistre_ts,
  186.     nb_messages_enregistre
  187. FROM normalized
  188. WHERE id IS NOT NULL
  189.   AND titre IS NOT NULL
  190.   AND COALESCE(
  191.         date_creation_ts,
  192.         date_dernier_message_ts,
  193.         date_dernier_message_enregistre_ts,
  194.         date_suppression_ts
  195.       ) IS NOT NULL
  196.   AND COALESCE(
  197.         date_dernier_message_ts,
  198.         date_dernier_message_enregistre_ts,
  199.         date_creation_ts,
  200.         date_suppression_ts
  201.       ) IS NOT NULL;
  202.  
  203. DROP TABLE topics_stage;
  204.  
  205. -- ------------------------------------------------------------
  206. -- Import MESSAGES directement dans le parent partitionné
  207. -- texte vide => '' au lieu de NULL
  208. -- ------------------------------------------------------------
  209. \echo Import messages depuis messages.csv
  210. \copy messages (id, date_post, texte, topic_id, auteur_id) FROM 'messages.csv' WITH (FORMAT csv, HEADER true, FORCE_NOT_NULL (texte))
  211.  
  212. -- ------------------------------------------------------------
  213. -- PK / contraintes d’unicité après chargement
  214. -- ------------------------------------------------------------
  215. ALTER TABLE auteurs
  216.     ADD CONSTRAINT auteurs_pk PRIMARY KEY (id);
  217.  
  218. ALTER TABLE topics
  219.     ADD CONSTRAINT topics_pk PRIMARY KEY (id);
  220.  
  221. ALTER TABLE messages
  222.     ADD CONSTRAINT messages_pk PRIMARY KEY (topic_id, id);
  223.  
  224. -- ------------------------------------------------------------
  225. -- Index secondaires
  226. -- ------------------------------------------------------------
  227. CREATE INDEX idx_auteurs_pseudo_trgm
  228.     ON auteurs
  229.     USING GIN ((lower(pseudo)) gin_trgm_ops);
  230.  
  231. CREATE INDEX idx_topics_last_active
  232.     ON topics (date_dernier_message DESC, id DESC)
  233.     WHERE date_suppression IS NULL;
  234.  
  235. CREATE INDEX idx_topics_auteur_last_active
  236.     ON topics (auteur_id, date_dernier_message DESC, id DESC)
  237.     WHERE auteur_id IS NOT NULL
  238.       AND date_suppression IS NULL;
  239.  
  240. CREATE INDEX idx_topics_date_creation
  241.     ON topics (date_creation DESC, id DESC);
  242.  
  243. CREATE INDEX idx_topics_titre_trgm
  244.     ON topics
  245.     USING GIN ((lower(titre)) gin_trgm_ops)
  246.     WHERE date_suppression IS NULL;
  247.  
  248. CREATE INDEX idx_messages_topic_date
  249.     ON messages (topic_id, date_post, id);
  250.  
  251. CREATE INDEX idx_messages_auteur_date
  252.     ON messages (auteur_id, date_post DESC, id DESC)
  253.     WHERE auteur_id IS NOT NULL;
  254.  
  255. -- ------------------------------------------------------------
  256. -- Stats
  257. -- ------------------------------------------------------------
  258. ANALYZE auteurs;
  259. ANALYZE topics;
  260. ANALYZE messages;
  261.  
Advertisement
Add Comment
Please, Sign In to add comment