Metadata Design and Engineering for a Film and TV Person-Works Database: Entity Modeling, Date Normalization, and Data Quality
A film or TV person page that lists a professional's works and premiere dates looks simple, but behind it sit entity modeling, field normalization, timeline management, and data quality governance. This article walks through the complete design of such a metadata system: a three-layer entity model (Person, Work, BroadcastRecord) that separates air dates from works; date normalization with precision flags to handle mixed formats such as "2019" and "2024-5-4"; layered storage across relational databases, search engines, and object storage; revision history for shifting schedules; data quality validation, sampling audits, and alerting; and API design principles. Reference SQL schemas and Python code for date parsing and validation are included.
1. Starting From a Typical Profile Page
In entertainment information systems, one of the most common page types is the person entry. The main body of such a page is a set of structured fields describing an industry professional, with the works list at its core—each record containing a title and its premiere date. For example, an entry may list two records: a series sequel that premiered on May 4, 2024, and a work that premiered in 2019. These pages look simple, yet they involve a chain of engineering problems: entity modeling, field normalization, timeline management, and data quality governance. This article uses this scenario as the starting point to walk through the design and implementation of a film and TV content metadata system.
2. Core Entity Modeling: Persons, Works, and Broadcast Records
1. A three-layer entity model
- Person: basic information about an industry professional, such as name, aliases, and occupation type.
- Work: an entry describing a TV series, film, variety show, or other content item.
- BroadcastRecord: the fact of a work first airing in a given region or channel.
The key design decision is to pull the “premiere date” out of the Work entity and model it as an independent broadcast record. There are three reasons. First, the same work may premiere at different times in different regions or channels. Second, a work may air long after production is complete—production year and premiere year are two different concepts. Third, a sequel should be an independent Work entity linked to the previous season through a “series” relationship, rather than having fields appended endlessly to the same record.
2. Reference table structure
CREATE TABLE person (id BIGINT PRIMARY KEY,name VARCHAR(128) NOT NULL,alias_json JSON,created_at DATETIME);CREATE TABLE work (id BIGINT PRIMARY KEY,title VARCHAR(256) NOT NULL,work_type TINYINT NOT NULL, -- enum: TV series / film / variety show, etc.series_id BIGINT NULL, -- owning series, where sequels belongseason_no INT NULL -- season number);CREATE TABLE broadcast_record (id BIGINT PRIMARY KEY,work_id BIGINT NOT NULL,air_date DATE NOT NULL,date_precision TINYINT NOT NULL, -- 1=year 2=month 3=dayregion VARCHAR(64),UNIQUE KEY uk_work_region (work_id, region));
3. Relationships
Persons and works form a many-to-many relationship, which should be modeled through a junction table that also carries role names, episode counts, and similar details. Pushing the works list directly into the person table would create heavy redundancy and update anomalies.
3. Field Normalization: Resolving “2019” vs. “2024-5-4”
Raw data often arrives with inconsistent date formats: some precise to the day, others carrying only a year. Writing them all into a single type loses semantic information. The recommended engineering approach is normalized storage plus a precision flag: dates are converted into a standard format while their precision is recorded alongside, and the frontend chooses the rendering based on precision (for example, “2019” or “2024-05-04”).
from datetime import datedef parse_airdate(raw: str):raw = raw.strip()if len(raw) == 4 and raw.isdigit():return date(int(raw), 1, 1), 1 # year onlyparts = raw.replace("年", "-").replace("月", "-").replace("日", "")seg = [int(p) for p in parts.split("-") if p]if len(seg) == 3:return date(*seg), 3if len(seg) == 2:return date(seg[0], seg[1], 1), 2raise ValueError(f"unrecognized airdate: {raw}")
The companion cleaning rules also include: unifying full-width and half-width characters and traditional/simplified script variants, trimming leading and trailing whitespace and invisible characters from titles, and merging different translated titles of the same work through an alias table. All cleaning logic should be designed to be idempotent, which makes repeated runs and incremental repairs safe.
4. Storage and Retrieval: Layered Selection
- Structured queries go to a relational database, covering core queries such as aggregating works by person and sorting by time.
- Fuzzy search (title keywords, alias hits) is delegated to a search engine component with an inverted index.
- Unstructured assets such as posters and stills are stored in object storage, with only resource identifiers kept in the database.
- Change logs for field updates are written to a log service, supporting auditing and problem tracing.
Cloud platforms such as Baidu AI Cloud offer common capabilities—object storage, log services, monitoring and alerting, and message queues—and each layer above can be assembled from these standard service categories without locking into any single vendor’s proprietary interfaces.
As for caching, a person page is a typical read-heavy, write-light scenario. Aggregated results per person are well suited to minute-level caching; when a work is edited, a message queue notifies each node to invalidate the related cache entries, guaranteeing eventual consistency.
5. Timeline and Version Management
- Air date revisions: A series premiere date often shifts as official scheduling is confirmed. The system should keep revision history (who changed the old value to the new value, and when) instead of overwriting in place, so that tracing and correction remain possible.
- Series and sequels: Season N is modeled as an independent Work attached to the same Series. List pages aggregate by series and sort by season number and air date, which naturally produces a “works chronology.”
- Future schedules: Broadcast records are allowed to carry dates later than the current time, marked as “unaired.” When the date arrives, a scheduled task flips them to “aired,” avoiding manual intervention.
6. Data Quality and Monitoring
A metadata database without quality governance degrades quickly. Three mechanisms are worth putting in place:
- Ingestion validation: required fields, date legality (no dates beyond a reasonable range), and enum constraints; records that fail validation are routed to a queue for manual handling.
- Sampling audits: periodically sample and compare source pages against in-database data, and record field-missing and inconsistency rates as quality metrics.
- Monitoring and alerting: set thresholds on collector success rate, cleaning failure rate, and field-missing rate; when an anomaly appears, notify on-call staff through alerting channels so they can intervene in time.
def validate(record):assert record["title"], "title required"d, p = parse_airdate(record["airdate"])assert d <= date.today() or p == 3, "future airdate must be precise"return {"air_date": d, "date_precision": p}
7. API Design and Presentation
A few principles for the external API: when aggregating works by person, return both the air date and its precision; support filtering by work type and year range; default list pagination to descending air-date order; and include a data version number in responses so clients can perform cache negotiation.
{"person": {"id": 1001, "name": "..."},"works": [{"workId": 9001, "title": "...", "airDate": "2024-05-04", "precision": "day"},{"workId": 8002, "title": "...", "airDate": "2019-01-01", "precision": "year"}]}
8. Summary
A film and TV person-works database is, at its core, a metadata engineering exercise combining entity modeling, time semantics, and quality governance. Three threads run through the practice: first, separate the three entities—person, work, and broadcast record—cleanly; second, resolve inconsistencies in dates and similar fields through normalization and precision flags; finally, hold the data quality line with versioning, ingestion validation, and monitoring. Build along this chain, and a seemingly simple profile page stays stable, trustworthy, and easy to extend even as data volume and update frequency keep growing.
