forked from niuniu/llm-intelligence
107 lines
4.3 KiB
MySQL
107 lines
4.3 KiB
MySQL
|
|
-- 日内新闻候选与验证持久化结构
|
|||
|
|
|
|||
|
|
CREATE TABLE IF NOT EXISTS intraday_news_candidate (
|
|||
|
|
id BIGSERIAL PRIMARY KEY,
|
|||
|
|
candidate_date DATE NOT NULL,
|
|||
|
|
discovered_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|||
|
|
event_type TEXT NOT NULL,
|
|||
|
|
provider_name TEXT NOT NULL,
|
|||
|
|
model_name TEXT,
|
|||
|
|
provider_country TEXT,
|
|||
|
|
title TEXT NOT NULL,
|
|||
|
|
summary TEXT,
|
|||
|
|
candidate_urls JSONB NOT NULL DEFAULT '[]'::jsonb,
|
|||
|
|
discovery_source TEXT NOT NULL,
|
|||
|
|
discovery_query TEXT,
|
|||
|
|
discovery_evidence JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|||
|
|
normalized_key TEXT NOT NULL,
|
|||
|
|
status TEXT NOT NULL DEFAULT 'candidate',
|
|||
|
|
verification_confidence TEXT NOT NULL DEFAULT 'candidate',
|
|||
|
|
verification_notes TEXT,
|
|||
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|||
|
|
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
DO $$
|
|||
|
|
BEGIN
|
|||
|
|
IF NOT EXISTS (
|
|||
|
|
SELECT 1 FROM pg_constraint WHERE conname = 'chk_intraday_news_candidate_status'
|
|||
|
|
) THEN
|
|||
|
|
ALTER TABLE intraday_news_candidate
|
|||
|
|
ADD CONSTRAINT chk_intraday_news_candidate_status
|
|||
|
|
CHECK (status IN ('candidate', 'verifying', 'verified', 'rejected', 'stale'));
|
|||
|
|
END IF;
|
|||
|
|
|
|||
|
|
IF NOT EXISTS (
|
|||
|
|
SELECT 1 FROM pg_constraint WHERE conname = 'chk_intraday_news_candidate_confidence'
|
|||
|
|
) THEN
|
|||
|
|
ALTER TABLE intraday_news_candidate
|
|||
|
|
ADD CONSTRAINT chk_intraday_news_candidate_confidence
|
|||
|
|
CHECK (verification_confidence IN ('candidate', 'secondary_confirmed', 'official_confirmed'));
|
|||
|
|
END IF;
|
|||
|
|
END
|
|||
|
|
$$;
|
|||
|
|
|
|||
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_intraday_news_candidate_normalized_key
|
|||
|
|
ON intraday_news_candidate(normalized_key);
|
|||
|
|
CREATE INDEX IF NOT EXISTS idx_intraday_news_candidate_date
|
|||
|
|
ON intraday_news_candidate(candidate_date DESC, discovered_at DESC);
|
|||
|
|
CREATE INDEX IF NOT EXISTS idx_intraday_news_candidate_status
|
|||
|
|
ON intraday_news_candidate(status);
|
|||
|
|
CREATE INDEX IF NOT EXISTS idx_intraday_news_candidate_provider_event
|
|||
|
|
ON intraday_news_candidate(provider_name, event_type, candidate_date DESC);
|
|||
|
|
|
|||
|
|
COMMENT ON TABLE intraday_news_candidate IS '搜索引擎与 LLM 发现的日内新闻候选池,尚未直接进入正式日报事实层';
|
|||
|
|
COMMENT ON COLUMN intraday_news_candidate.candidate_urls IS '候选来源 URL 数组,按发现层输出原样保留';
|
|||
|
|
COMMENT ON COLUMN intraday_news_candidate.discovery_evidence IS '发现阶段原始证据 JSONB,例如搜索命中、LLM 归纳结果';
|
|||
|
|
COMMENT ON COLUMN intraday_news_candidate.normalized_key IS '同日同事件的去重键,避免重复发现候选';
|
|||
|
|
|
|||
|
|
CREATE TABLE IF NOT EXISTS intraday_news_verification (
|
|||
|
|
id BIGSERIAL PRIMARY KEY,
|
|||
|
|
candidate_id BIGINT NOT NULL REFERENCES intraday_news_candidate(id) ON DELETE CASCADE,
|
|||
|
|
verified_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|||
|
|
verifier_source TEXT NOT NULL,
|
|||
|
|
verifier_url TEXT,
|
|||
|
|
verifier_status TEXT NOT NULL,
|
|||
|
|
extracted_facts JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|||
|
|
notes TEXT,
|
|||
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
DO $$
|
|||
|
|
BEGIN
|
|||
|
|
IF NOT EXISTS (
|
|||
|
|
SELECT 1 FROM pg_constraint WHERE conname = 'chk_intraday_news_verification_status'
|
|||
|
|
) THEN
|
|||
|
|
ALTER TABLE intraday_news_verification
|
|||
|
|
ADD CONSTRAINT chk_intraday_news_verification_status
|
|||
|
|
CHECK (verifier_status IN ('matched', 'contradicted', 'insufficient', 'error'));
|
|||
|
|
END IF;
|
|||
|
|
END
|
|||
|
|
$$;
|
|||
|
|
|
|||
|
|
CREATE INDEX IF NOT EXISTS idx_intraday_news_verification_candidate_verified_at
|
|||
|
|
ON intraday_news_verification(candidate_id, verified_at DESC);
|
|||
|
|
CREATE INDEX IF NOT EXISTS idx_intraday_news_verification_source
|
|||
|
|
ON intraday_news_verification(verifier_source);
|
|||
|
|
CREATE INDEX IF NOT EXISTS idx_intraday_news_verification_status
|
|||
|
|
ON intraday_news_verification(verifier_status);
|
|||
|
|
|
|||
|
|
COMMENT ON TABLE intraday_news_verification IS '日内新闻候选的验证轨迹,记录验证来源、状态和提取事实';
|
|||
|
|
COMMENT ON COLUMN intraday_news_verification.extracted_facts IS '验证阶段提取出的结构化事实 JSONB';
|
|||
|
|
|
|||
|
|
DO $$
|
|||
|
|
BEGIN
|
|||
|
|
IF NOT EXISTS (
|
|||
|
|
SELECT 1
|
|||
|
|
FROM pg_trigger
|
|||
|
|
WHERE tgname = 'intraday_news_candidate_updated_at'
|
|||
|
|
) THEN
|
|||
|
|
CREATE TRIGGER intraday_news_candidate_updated_at
|
|||
|
|
BEFORE UPDATE ON intraday_news_candidate
|
|||
|
|
FOR EACH ROW
|
|||
|
|
EXECUTE FUNCTION update_updated_at_column();
|
|||
|
|
END IF;
|
|||
|
|
END
|
|||
|
|
$$;
|