算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
relational-data-modeling【设计与创意】Corrects the wrong defaults a model has when designing a relational schema — the DDL decisions an experienced engineer makes differently. Use when creating or reviewing tables, migrations, ER models, or ORM schema definitions. Covers identity and keys (surrogate vs natural, identity vs serial, uuidv7, composite keys that make cross-tenant references …
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
The decisions a relational schema forces, and how to settle them so the database enforces what it can and the application is left with only what it must. Every rule names the wrong default it corrects; there is no rule for what a capable model already gets right.
Examples are PostgreSQL 18, and every DDL statement in this skill was
executed against 18.4 — including the failure cases, to confirm the constraints
reject what they claim to reject. Roughly a third of the rules depend on
mechanisms MySQL and SQLite do not have (EXCLUDE, partial unique indexes,
range types, WITHOUT OVERLAPS, deferrable constraints, NOT VALID); those
rules say so. The judgment rules transfer to any relational engine.
Use this skill when:
CREATE TABLE / ALTER TABLE, a migration, or an ORM
schema definition (Prisma, Drizzle, Django models, ActiveRecord, Ecto, SQLAlchemy)This skill is NOT for:
| # | Category | Prefix | Covers |
|---|---|---|---|
| 1 | Identity and Keys | key- | What a row is; the choice every foreign key depends on |
| 2 | Relationships and Cardinality | rel- | Keeping references declarable to the database, not just intended |
| 3 | Constraints as the Model | cons- | Which mechanism can actually hold which invariant |
| 4 | Types and Domains | type- | The cheapest constraint available, chosen for meaning not habit |
| 5 | Derived and Encoded Data | norm- | What every deliberate copy costs, and what the database can't see inside |
| 6 | Time, History and Lifecycle | time- | What happens to a row when the world changes |
key-primary-key-is-real-identity — a surrogate hides the natural key; you still owe the table a UNIQUEkey-identity-not-serial — serial is legacy; GENERATED ALWAYS AS IDENTITY blocks the desync that breaks insertskey-uuidv7-for-client-generated — v4 randomises every B-tree insert; use uuidv7(), and only when a UUID is earnedkey-propagate-scoping-key — carry the tenant into child keys so a cross-tenant reference cannot be writtenkey-partition-axis-binds-the-key — for tables that grow with traffic, the partition axis is a key decision, not later tuningrel-no-polymorphic-fk — type + id makes referential integrity undeclarable; use an exclusive arc or a supertyperel-relationship-as-entity — name it if it has facts and a lifecycle; keep it a keyed link table if it doesn'trel-choose-referential-action — CASCADE means composition; on a ledger it is data lossrel-index-referencing-side — PostgreSQL does not index the child column; MySQL does, and the habit transfersrel-one-to-one-is-one-table — a split buys a join and enforces nothing unless storage or access control differsrel-subtypes-through-the-key — UNIQUE (id, kind) plus a pinned discriminator proves the variants are disjointcons-not-null-by-default — a CHECK that evaluates to NULL passes, and UNIQUE stops constrainingcons-exclude-for-non-overlap — the app-level overlap check is a read-then-write race; EXCLUDE is notcons-partial-unique-index — "at most one active X" is a UNIQUE ... WHERE, not a triggercons-check-is-single-row — wrapping a query in a function makes a CHECK that silently stops holdingcons-deferrable-for-cycles — defer to COMMIT instead of making a column nullable forevercons-not-valid-then-validate — what makes constraints addable to a live table at alltype-timestamptz-for-instants — timestamp stores a wall clock with no zone; a birthday is not an instanttype-text-over-varchar — varchar(255) is a MySQL artifact; a length limit is a CHECK or a domaintype-numeric-with-currency — floats drift, money is locale-dependent, and currency is never implicittype-range-not-two-columns — two loose columns admit inverted rows and block every temporal constrainttype-enum-lookup-or-check — CHECK by default, lookup table when values carry attributes, enum is a one-way doornorm-derived-needs-a-mechanism — no constraint can hold two copies equal; name the mechanism or don't copynorm-encoded-composite-values — generate the reference code from its parts; a parsed column can't be constrainednorm-jsonb-for-open-shapes — if you can enumerate the keys and filter on one, they are columnstime-events-not-in-place-updates — an in-place balance destroys the audit trail and serialises the accounttime-soft-delete-breaks-constraints — deleted_at disables unique constraints and foreign keys silentlytime-validity-as-a-range — WITHOUT OVERLAPS makes two simultaneous versions unrepresentabletime-valid-vs-transaction-time — two axes only when you must reproduce a past belief; usually you must notRead a reference file when its decision comes up — the quick reference above is enough to route. Each rule states the wrong default it corrects and why, then gives a canonical example.
Two rules of thumb tie the categories together and are worth applying even outside a specific rule:
cons-check-is-single-row for
the map of invariant shapes to mechanisms.| File | Description |
|---|---|
| references/_sections.md | Category definitions and ordering |
| assets/templates/_template.md | Template for new rules |
| metadata.json | Version and source references |