KB-2870

Mẫu hiển thị Nuxt — PG read PG

8 min read Revision 1
laws-newpg-read-pgform-nuxtdisplay-specread-onlyview-not-tablenhom-aread-card2026-06-24

MẪU HIỂN THỊ NUXT — PG read PG

File: knowledge/dev/laws-new/pg-read-pg/form-nuxt-report.md Thuộc đề bài: de-bai-pg-read-pg.md (v1.1) · Ngày: 2026-06-24 Mục đích: Định nghĩa mẫu các bảng cần hiển thị lên Nuxt cho PG read PG (Read Card 01 + 02). Mỗi bảng = một view read-only = một câu lệnh.

Nguyên tắc hiển thị (đọc trước)

  • 1 bảng = 1 câu đọc (1 view). Sáu bảng dưới đây = sáu SELECT độc lập. Sai bảng nào sửa bảng đó.
  • Số liệu LIVE từ view, KHÔNG hardcode. Các con số "ví dụ" ghi trong file này chỉ là ảnh chụp ngày 2026-06-24 để đối chiếu; nguồn sự thật là view chạy lúc render (§0-AU cấm hardcode).
  • Hiển thị = lắp view vào renderer CÓ SẴN (Đ28). KHÔNG viết component/khuôn Nuxt mới. Nuxt chưa hiện = chưa tìm ra khuôn cũ, KHÔNG phải hệ thống thiếu.
  • Xuất VIEW, không tạo TABLE lưu số.
  • Tất cả là Nhóm A (PG tự khai) — trung tính, không gán nghĩa vai trò.

BẢNG 0 — CENSUS TỔNG (master) — Read Card 01

Mục đích: một chỗ thấy hệ có những LOẠI thực thể gì, mỗi loại bao nhiêu. Cột hiển thị: STT · Loại thực thể (PG tự biết) · Tổng số · Bảng con Sắp xếp: theo thứ tự logic dưới (giữ nguyên STT). Filter: theo loại. Nguồn (1 câu, UNION ALL):

SELECT 'table' AS object_kind, count(*) AS n FROM pg_class c JOIN pg_namespace n ON n.oid=c.relnamespace WHERE n.nspname='public' AND c.relkind='r'
UNION ALL SELECT 'view', count(*) FROM pg_class c JOIN pg_namespace n ON n.oid=c.relnamespace WHERE n.nspname='public' AND c.relkind='v'
UNION ALL SELECT 'matview', count(*) FROM pg_class c JOIN pg_namespace n ON n.oid=c.relnamespace WHERE n.nspname='public' AND c.relkind='m'
UNION ALL SELECT 'sequence', count(*) FROM pg_class c JOIN pg_namespace n ON n.oid=c.relnamespace WHERE n.nspname='public' AND c.relkind='S'
UNION ALL SELECT 'foreign_table', count(*) FROM pg_class c JOIN pg_namespace n ON n.oid=c.relnamespace WHERE n.nspname='public' AND c.relkind='f'
UNION ALL SELECT 'index', count(*) FROM pg_class c JOIN pg_namespace n ON n.oid=c.relnamespace WHERE n.nspname='public' AND c.relkind='i'
UNION ALL SELECT 'function', count(*) FROM pg_proc p JOIN pg_namespace n ON n.oid=p.pronamespace WHERE n.nspname='public' AND p.prokind='f'
UNION ALL SELECT 'procedure', count(*) FROM pg_proc p JOIN pg_namespace n ON n.oid=p.pronamespace WHERE n.nspname='public' AND p.prokind='p'
UNION ALL SELECT 'trigger', count(*) FROM pg_trigger WHERE NOT tgisinternal
UNION ALL SELECT 'constraint', count(*) FROM pg_constraint con JOIN pg_namespace n ON n.oid=con.connamespace WHERE n.nspname='public'
UNION ALL SELECT 'column', count(*) FROM information_schema.columns WHERE table_schema='public'
UNION ALL SELECT 'schema', count(*) FROM information_schema.schemata WHERE schema_name NOT IN ('pg_catalog','information_schema') AND schema_name NOT LIKE 'pg_%';

Cảnh báo: trigger PHẢI đọc qua pg_catalog.pg_trigger (như trên). information_schema.triggers lọc theo quyền → trả 0 GIẢ.

Ví dụ kết quả (2026-06-24 — chỉ để đối chiếu):

STT Loại thực thể Tổng số Bảng con
1 schema 2
2 table 380 ✓ Bảng 1
3 view 699
4 materialized view 1
5 sequence 146
6 function 654 ✓ Bảng 3
7 procedure 1
8 trigger 410 ✓ Bảng 4
9 constraint 974 ✓ Bảng 5
10 index 1.357
11 foreign table 1
12 column / field ~9.420 ✓ Bảng 2

BẢNG 1 — TABLE theo HỌ — Read Card 02

Mục đích: table chia theo họ (tiền tố tên) để thấy domain nào lớn/nhỏ. Cột: STT · Họ (family) · Số bảng · Dòng (ước lượng) Sắp xếp: số bảng giảm dần. Filter: theo họ. Nguồn (1 câu):

SELECT CASE WHEN left(c.relname,1)='_' THEN '(scratch_underscore)'
            ELSE split_part(c.relname,'_',1) END AS family,
       count(*) AS so_bang,
       sum(c.reltuples)::bigint AS dong_uoc_luong
FROM pg_class c JOIN pg_namespace n ON n.oid=c.relnamespace
WHERE n.nspname='public' AND c.relkind='r'
GROUP BY 1 ORDER BY so_bang DESC;

Ví dụ (2026-06-24): iu 31 · directus 27 · block 25 · wf 24 · os 24 · qt001 20 · tac 14 · dot 11 · governance 10 · kg 8 · birth 6 · … (~20 họ). (reltuples = -1 = chưa ANALYZE = nghi vỏ rỗng.)


BẢNG 2 — COLUMN/FIELD theo KIỂU DỮ LIỆU

Mục đích: field chia theo kiểu dữ liệu (mỗi kiểu một dòng). Cột: STT · Kiểu dữ liệu (data_type) · Số lượng Sắp xếp: số lượng giảm dần. Filter: theo kiểu. Nguồn (1 câu):

SELECT data_type, count(*) AS n
FROM information_schema.columns
WHERE table_schema='public'
GROUP BY data_type ORDER BY n DESC LIMIT 10;

Ví dụ (2026-06-24): text 3.974 · boolean 1.189 · bigint 941 · character varying (varchar) 838 · integer 753 · timestamp with time zone (timestamptz) 463 · jsonb 239 · uuid 169 · numeric 151 · ARRAY 48.

Nhãn dòng = giá trị data_type thật PG trả về; tên rút gọn (varchar, timestamptz) chỉ để dễ đọc.


BẢNG 3 — FUNCTION theo KIỂU TRẢ VỀ

Mục đích: function chia theo cái PG biết = kiểu trả về (trung tính, KHÔNG gọi "checker"). Cột: STT · Kiểu trả về · Số lượng Sắp xếp: số lượng giảm dần. Nguồn (1 câu):

SELECT CASE
  WHEN pg_get_function_result(p.oid)='trigger' THEN 'trigger-fn'
  WHEN pg_get_function_result(p.oid)='boolean' THEN 'tra-ve-boolean'
  WHEN pg_get_function_result(p.oid) LIKE 'SETOF%' OR pg_get_function_result(p.oid) LIKE 'TABLE%' THEN 'tra-ve-bang'
  WHEN pg_get_function_result(p.oid)='void' THEN 'void'
  ELSE 'scalar/khac' END AS kieu_tra_ve,
  count(*) AS n
FROM pg_proc p JOIN pg_namespace n ON n.oid=p.pronamespace
WHERE n.nspname='public' AND p.prokind='f'
GROUP BY 1 ORDER BY n DESC;

Ví dụ (2026-06-24): scalar/khác 388 · trigger-fn 127 · trả-về-bảng 62 · trả-về-boolean 54 · void 15.


BẢNG 4 — TRIGGER theo THỜI ĐIỂM × SỰ KIỆN

Mục đích: trigger chia theo "canh lúc nào, sự kiện gì". Cột: STT · Thời điểm × Sự kiện · Số lượng Sắp xếp: số lượng giảm dần. Nguồn (1 câu):

SELECT (CASE WHEN (t.tgtype & 2)>0 THEN 'BEFORE' ELSE 'AFTER' END)
       ||' '||
       (CASE WHEN (t.tgtype & 4)>0 THEN 'INSERT'
             WHEN (t.tgtype & 8)>0 THEN 'DELETE'
             WHEN (t.tgtype & 16)>0 THEN 'UPDATE' ELSE 'multi' END) AS thoi_diem_su_kien,
       count(*) AS n
FROM pg_trigger t WHERE NOT t.tgisinternal
GROUP BY 1 ORDER BY n DESC;

Ví dụ (2026-06-24): AFTER INSERT 274 · BEFORE INSERT 106 · BEFORE UPDATE 22 · BEFORE DELETE 4 · AFTER UPDATE 3 · AFTER DELETE 1. (~92% canh lúc INSERT.)


BẢNG 5 — CONSTRAINT theo LOẠI

Mục đích: ràng buộc chia theo loại; nổi bật FK = quan hệ bảng↔bảng. Cột: STT · Loại · Số lượng Sắp xếp: số lượng giảm dần. Nguồn (1 câu):

SELECT CASE contype WHEN 'p' THEN 'PRIMARY KEY' WHEN 'f' THEN 'FOREIGN KEY'
            WHEN 'u' THEN 'UNIQUE' WHEN 'c' THEN 'CHECK' ELSE contype::text END AS loai,
       count(*) AS n
FROM pg_constraint con JOIN pg_namespace n ON n.oid=con.connamespace
WHERE n.nspname='public'
GROUP BY 1 ORDER BY n DESC;

Ví dụ (2026-06-24): PRIMARY KEY 336 · CHECK 332 · FOREIGN KEY 119 · UNIQUE 74.


Tóm tắt cho người dựng

  • 6 bảng = 6 câu đọc = 6 view. Mỗi câu read-only, trả một bảng nhỏ (đều < 50 dòng trừ census 12 dòng).
  • Đăng ký 6 view vào Directus → render bằng khuôn Nuxt đã có (bảng có STT + filter). Không code mới.
  • Số trong file này là ví dụ đối chiếu, không nhúng cứng; Nuxt hiển thị kết quả view lúc chạy.
  • Nghiệm thu = mở URL Nuxt thật, thấy 6 bảng hiện số (MERGE ≠ DONE).