فهرست مقاله
فرض کنید برنامهای برای هر کانال، چند نسخهٔ کالیبراسیون نگه میدارد. نسخههای قدیمی باید برای بررسی بعدی باقی بمانند، اما همزمان نباید دو نسخهٔ فعال برای همان کانال داشته باشیم. افزودن UNIQUE به شناسهٔ کانال، تاریخچه را هم ممنوع میکند؛ حذف کامل یکتایی نیز اجازهٔ دو انتخاب فعال میدهد. این آموزش قاعدهٔ میانی را در یک آزمایش کوچک و تکرارپذیر میسنجد. تمام دادهها ساختگیاند و پایگاه داده فقط در حافظهٔ خصوصی یک اتصال ساخته میشود.
۱. یک کالیبراسیون فعال، با تاریخچهٔ غیرفعال

هر ردیف چهار مقدار دارد: شناسهٔ نسخه، شناسهٔ کانال، پرچم فعال و offset صحیح برحسب میلیولت. offset در اینجا فقط فرادادهٔ ذخیرهشده است؛ برنامه ولتاژ دستگاهی را اندازه نمیگیرد و تصحیح فیزیکی انجام نمیدهد. شناسهها و دامنهها قرارداد آموزشی نویسندهاند: نسخه از یک تا شش، کانال از صفر تا دو، پرچم صفر یا یک و offset از منفی پنج تا مثبت پنج میلیولت.
قاعده را دقیق بنویسیم: برای هر کانال، حداکثر یک ردیف با active برابر یک مجاز است. وجود چند ردیف غیرفعال اشکالی ندارد. همچنین کانالی بدون ردیف فعال معتبر است؛ «حداکثر یک» به معنای «حتماً یکی» نیست. اگر برنامهٔ واقعی نبودن کالیبراسیون فعال را نمیپذیرد، به قاعدهٔ جداگانهای برای آن نیاز دارد. این نمونه چنین شرطی را پنهانی به یکتایی اضافه نمیکند.
سه ردیف نخستِ شاهد دستی، همگی متعلق به کانال صفرند. نسخههای یک و دو غیرفعالاند و offset آنها منفی دو و مثبت یک میلیولت است؛ نسخهٔ سه با offset صفر فعال است. اضافهشدن نسخهٔ چهارِ فعال باید رد شود. سپس نسخهٔ سه غیرفعال و نسخهٔ دو فعال میشود؛ نسخههای تاریخی همچنان باقی میمانند. برای تفکیک نوع ورودی از مقدار ذخیرهشده، درس قرارداد نوع در SQLite زمینهٔ مناسبی است؛ مسئلهٔ حاضر، رابطهٔ بین چند ردیف است.
۲. قیدِ یکتایی فقط روی زیرمجموعهٔ درست

نمایهٔ انتخابشده یک کلید دارد: channel. بند WHERE با شرط active=1 تعیین میکند کدام ردیفها در آن حضور داشته باشند. طبق سند رسمی نمایههای جزئی SQLite، فقط ردیفهای دارای نتیجهٔ درست وارد نمایه میشوند؛ نتیجهٔ نادرست یا NULL کنار میماند. افزودن UNIQUE، کلیدهای همین زیرمجموعه را یکتا میکند. بنابراین تاریخچهٔ غیرفعال خارج از رقابت بر سر جایگاه فعال میماند.
قید مرکب UNIQUE(channel,active) جایگزین هممعنایی نیست: دو ردیف غیرفعالِ کانال صفر، زوج یکسانِ صفر و صفر دارند و ردیف دوم رد میشود. این شکست از خراببودن تاریخچه نمیآید؛ قید نامناسب، درخواست ما را بیش از حد محدود کرده است. آزمایش جانبی، همین شاهد نقض را در جدولی جدا ثبت میکند؛ جدول اصلی و نتیجهٔ مورد انتظار برای پذیرفتن آن دستکاری نمیشوند.
دو شکافِ مقدار تهی را نیز جدا ببینیم. اگر خودِ channel تهی باشد، تعریف رسمی CREATE INDEX میگوید کلیدهای NULL در نمایهٔ یکتا از یکدیگر متمایز محسوب میشوند. اگر active تهی باشد، شرط عضویت نتیجهٔ NULL میدهد و آن ردیف وارد نمایه نمیشود. این دو سازوکار یک چیز نیستند. مسیر اصلی ورودیِ تهی و پرچمِ خارج از صفر و یک را رد میکند؛ کنترلهای عمداً ضعیفشده فقط برای دیدن تفاوت این قواعد هستند.
۳. کد کامل و آزمایشِ حافظهایِ محدود

تابع replay یک tuple دقیق از حداکثر شش فرمان میپذیرد. فرمانها درج، تغییر پرچم، انتقال کانال و حذفاند. تمام شکلها، نوعها و دامنهها پیش از بازشدن اتصال بررسی میشوند؛ bool با وجود نسبت نوعیاش با int پذیرفته نیست. مولد نیز ورودی معتبر نیست و برای تشخیص نامعتبر بودنش مصرف نمیشود. نام جدول و دستورات ثابتاند و مقدارها با جاینگهدار به SQL داده میشوند.
اتصال autocommit=True دارد و هر فرمان، یک دستور مستقل است. خروجی هر مرحله وضعیت applied، conflict یا missing و تمام ردیفهای مرتبشده برحسب شناسه را نگه میدارد. تغییرِ شناسهٔ ناموجود missing است؛ تلاش برای شناسهٔ تکراری یا فعالکردن جایگاه اشغالشده conflict میشود. فقط IntegrityError مورد انتظار گرفته میشود؛ خطای دیگری نباید با برچسب تعارض پنهان شود. اتصال در finally بسته میشود.
"""Conditional uniqueness for bounded synthetic calibration history, in memory."""
import itertools
import json
import platform
import sqlite3
import sys
MAX_COMMANDS = 6
SCHEMA = """CREATE TABLE calibration(
row_id INTEGER PRIMARY KEY,
channel INTEGER NOT NULL,
active INTEGER NOT NULL,
offset_mv INTEGER NOT NULL
)"""
INDEX = "CREATE UNIQUE INDEX one_active ON calibration(channel) WHERE active=1"
SNAPSHOT = "SELECT row_id,channel,active,offset_mv FROM calibration ORDER BY row_id"
def exact_integer(value, lower, upper):
if type(value) is not int:
raise TypeError("exact int required; bool and coercion are excluded")
if not lower <= value <= upper:
raise ValueError("outside the authored finite integer domain")
return value
def validate_commands(commands):
"""Validate every command before opening a connection or executing SQL."""
if type(commands) is not tuple:
raise TypeError("an exact tuple of command tuples is required")
if len(commands) > MAX_COMMANDS:
raise ValueError("at most six commands per replay")
for command in commands:
if type(command) is not tuple:
raise TypeError("each command must be an exact tuple")
if not command:
raise ValueError("empty command")
if type(command[0]) is not str:
raise TypeError("exact str operation required")
op = command[0]
lengths = {"add": 5, "active": 3, "move": 3, "drop": 2}
if op not in lengths or len(command) != lengths[op]:
raise ValueError("unknown operation or wrong field count")
exact_integer(command[1], 1, 6)
if op == "add":
exact_integer(command[2], 0, 2)
exact_integer(command[3], 0, 1)
exact_integer(command[4], -5, 5)
elif op == "active":
exact_integer(command[2], 0, 1)
elif op == "move":
exact_integer(command[2], 0, 2)
def replay(commands):
"""Return complete states after each single sequential SQL statement.
This API has no operation to demand that an active row exists. The index
enforces only the upper bound, for valid nonnull application inputs.
"""
validate_commands(commands)
connection = sqlite3.connect(":memory:", autocommit=True)
events = []
try:
connection.execute(SCHEMA)
connection.execute(INDEX)
for command in commands:
op = command[0]
try:
if op == "add":
cursor = connection.execute(
"INSERT INTO calibration VALUES(?,?,?,?)", command[1:])
elif op == "active":
cursor = connection.execute(
"UPDATE calibration SET active=? WHERE row_id=?",
(command[2], command[1]))
elif op == "move":
cursor = connection.execute(
"UPDATE calibration SET channel=? WHERE row_id=?",
(command[2], command[1]))
else:
cursor = connection.execute(
"DELETE FROM calibration WHERE row_id=?", command[1:])
status = "applied" if cursor.rowcount else "missing"
except sqlite3.IntegrityError:
# Only the expected PK/conditional-UNIQUE conflicts reach here
# for validated inputs and this fixed, sequential schema.
status = "conflict"
rows = tuple(connection.execute(SNAPSHOT).fetchall())
events.append({"command": command, "status": status, "rows": rows})
return tuple(events)
finally:
connection.close()
def record_oracle(commands):
"""Independent valid-input reference: candidate relations, no SQL or API call.
It compares all pairs after a proposed transformation instead of using an
index, a channel map, the production mutator, or SQLite's result.
"""
state = ()
result = []
for command in commands:
op, row_id = command[:2]
present = any(row[0] == row_id for row in state)
if op == "add":
candidate = state + (tuple(command[1:]),)
elif not present:
result.append({"command": command, "status": "missing", "rows": state})
continue
elif op == "drop":
candidate = tuple(row for row in state if row[0] != row_id)
elif op == "active":
candidate = tuple((row[0], row[1], command[2], row[3])
if row[0] == row_id else row for row in state)
else:
candidate = tuple((row[0], command[2], row[2], row[3])
if row[0] == row_id else row for row in state)
invalid = any(
left[0] == right[0] or
(left[2] == right[2] == 1 and left[1] == right[1])
for i, left in enumerate(candidate) for right in candidate[i + 1:])
status = "conflict" if invalid else "applied"
if not invalid:
state = tuple(sorted(candidate))
result.append({"command": command, "status": status, "rows": state})
return tuple(result)
def rejects(call, exception):
try:
call()
except exception:
return True
return False
def weakened_controls():
"""Deliberately different schemas; NULL is not a valid main-API input."""
connection = sqlite3.connect(":memory:", autocommit=True)
try:
connection.execute("CREATE TABLE overstrict(channel INTEGER,active INTEGER,"
"UNIQUE(channel,active))")
connection.execute("INSERT INTO overstrict VALUES(0,0)")
overstrict = rejects(
lambda: connection.execute("INSERT INTO overstrict VALUES(0,0)"),
sqlite3.IntegrityError)
connection.execute("CREATE TABLE nullable_key(channel INTEGER,active INTEGER)")
connection.execute("CREATE UNIQUE INDEX nullable_one ON nullable_key(channel) "
"WHERE active=1")
connection.executemany("INSERT INTO nullable_key VALUES(?,?)", ((None, 1),) * 2)
null_keys = tuple(connection.execute("SELECT * FROM nullable_key ORDER BY rowid").fetchall())
connection.execute("CREATE TABLE nullable_flag(channel INTEGER,active INTEGER)")
connection.execute("CREATE UNIQUE INDEX flag_one ON nullable_flag(channel) "
"WHERE active=1")
connection.executemany("INSERT INTO nullable_flag VALUES(?,?)",
((0, None), (0, None), (0, 1)))
repeated_active = rejects(
lambda: connection.execute("INSERT INTO nullable_flag VALUES(0,1)"),
sqlite3.IntegrityError)
null_flags = tuple(connection.execute("SELECT * FROM nullable_flag ORDER BY rowid").fetchall())
return {"composite_unique_rejected_second_inactive": overstrict,
"indexed_null_key_rows": null_keys,
"predicate_null_rows_and_active": null_flags,
"second_nonnull_active_rejected": repeated_active}
finally:
connection.close()
def strict_input_checks():
class IntegerSubclass(int):
pass
class TupleSubclass(tuple):
pass
class StringSubclass(str):
pass
consumed = []
def lazy():
consumed.append(True)
yield ("add", 1, 0, 0, 0)
bad_types = [None, [], lazy(), TupleSubclass(),
(["add", 1, 0, 0, 0],),
((StringSubclass("drop"), 1),),
((1, 1),)]
for position in range(1, 5):
for value in (True, 1.0, "1", None, IntegerSubclass(1)):
command = ["add", 1, 0, 0, 0]
command[position] = value
bad_types.append((tuple(command),))
# A valid prefix must not open a connection before an invalid suffix is read.
bad_types.append((("add", 1, 0, 0, 0), ("active", 1, True)))
bad_bounds = [(("add", 0, 0, 0, 0),), (("add", 7, 0, 0, 0),),
(("add", 1, -1, 0, 0),), (("add", 1, 3, 0, 0),),
(("add", 1, 0, -1, 0),), (("add", 1, 0, 2, 0),),
(("add", 1, 0, 0, -6),), (("add", 1, 0, 0, 6),),
(("move", 1, 3),), (("active", 1, 2),),
((),), (("unknown", 1),), (("drop",),),
(("drop", 1, 0),), (("drop", 1),) * 7]
attempts = []
actual_connect = sqlite3.connect
def forbidden_connect(*args, **kwargs):
attempts.append((args, kwargs))
raise AssertionError("SQL opened before complete validation")
try:
sqlite3.connect = forbidden_connect
types_ok = all(rejects(lambda value=value: replay(value), TypeError)
for value in bad_types)
bounds_ok = all(rejects(lambda value=value: replay(value), ValueError)
for value in bad_bounds)
finally:
sqlite3.connect = actual_connect
return {"types_ok": types_ok and consumed == [] and attempts == [],
"bounds_ok": bounds_ok and attempts == [],
"invalid_type_cases": len(bad_types),
"invalid_bound_or_shape_cases": len(bad_bounds),
"connect_attempts_for_all_invalid_inputs": len(attempts),
"generator_consumed": bool(consumed)}
def resource_and_freshness_checks():
actual_connect = sqlite3.connect
closed = []
inject = [False]
sentinel = RuntimeError("expected injected snapshot failure")
class TrackedConnection:
def __init__(self, connection):
self.connection = connection
def execute(self, sql, parameters=()):
if inject[0] and sql == SNAPSHOT:
raise sentinel
return self.connection.execute(sql, parameters)
def close(self):
closed.append(True)
self.connection.close()
def tracked_connect(*args, **kwargs):
return TrackedConnection(actual_connect(*args, **kwargs))
try:
sqlite3.connect = tracked_connect
first = replay((("add", 1, 0, 0, -5),))
second = replay((("add", 1, 0, 0, -5),))
empty = replay(())
inject[0] = True
caught = None
try:
replay((("add", 1, 0, 0, 0),))
except RuntimeError as error:
caught = error
finally:
sqlite3.connect = actual_connect
first[0]["status"] = "caller_changed_own_report"
fresh = second == ({"command": ("add", 1, 0, 0, -5), "status": "applied",
"rows": ((1, 0, 0, -5),)},)
immutable_rows = rejects(lambda: second[0]["rows"][0].__setitem__(1, 2), AttributeError)
return {"passed": fresh and immutable_rows and empty == () and
caught is sentinel and closed == [True] * 4,
"tracked_connections_closed": len(closed),
"expected_injected_error_identity_preserved": caught is sentinel}
def run_example():
checks = {}
def check(name, condition):
if type(condition) is not bool:
raise AssertionError("Each named group must be an actual bool")
checks[name] = condition
if not condition:
raise AssertionError(name)
commands = (("add", 1, 0, 0, -2), ("add", 2, 0, 0, 1),
("add", 3, 0, 1, 0), ("add", 4, 0, 1, 2),
("active", 3, 0), ("active", 2, 1))
manual = replay(commands)
hand_before = ((1, 0, 0, -2), (2, 0, 0, 1), (3, 0, 1, 0))
hand_final = ((1, 0, 0, -2), (2, 0, 1, 1), (3, 0, 0, 0))
check("manual_history_and_single_active", manual[2]["rows"] == hand_before)
check("conflicting_insert_preserves_previous_state",
manual[3]["status"] == "conflict" and manual[3]["rows"] == hand_before)
separate = replay((("add", 1, 0, 1, -5), ("add", 2, 2, 1, 5)))
check("channels_have_independent_active_slots",
separate[-1]["rows"] == ((1, 0, 1, -5), (2, 2, 1, 5)))
check("deactivation_releases_slot_for_another_history_row",
manual[-2]["status"] == manual[-1]["status"] == "applied" and
manual[-1]["rows"] == hand_final)
activation = replay((("add", 1, 0, 0, 0), ("add", 2, 0, 1, 3), ("active", 1, 1)))
check("activating_existing_history_also_checks_uniqueness",
activation[-1]["status"] == "conflict" and
activation[-1]["rows"] == activation[-2]["rows"])
move = replay((("add", 1, 0, 1, 0), ("add", 2, 1, 1, 2),
("move", 2, 0), ("move", 2, 2)))
check("moving_active_row_rejects_occupied_and_accepts_free_channel",
move[2]["status"] == "conflict" and move[2]["rows"] == move[1]["rows"] and
move[-1]["rows"] == ((1, 0, 1, 0), (2, 2, 1, 2)))
deletion = replay((("add", 1, 0, 1, 0), ("add", 2, 0, 0, 2),
("add", 3, 0, 0, -1), ("drop", 1), ("active", 2, 1)))
check("deleting_active_row_preserves_history_and_releases_slot",
deletion[-1]["rows"] == ((2, 0, 1, 2), (3, 0, 0, -1)))
controls = weakened_controls()
check("ordinary_composite_unique_overrestricts_inactive_history",
controls["composite_unique_rejected_second_inactive"] is True)
check("nullable_indexed_key_does_not_enforce_main_channel_rule",
controls["indexed_null_key_rows"] == ((None, 1), (None, 1)))
check("predicate_null_is_outside_partial_index",
controls["predicate_null_rows_and_active"] == ((0, None), (0, None), (0, 1)) and
controls["second_nonnull_active_rejected"] is True)
invalid = strict_input_checks()
check("strict_types_and_complete_prevalidation_before_SQL", invalid["types_ok"])
missing = replay((("active", 6, 1), ("move", 6, 2), ("drop", 6),
("add", 6, 2, 1, 5)))
check("authored_bounds_shapes_and_missing_row_policy",
invalid["bounds_ok"] and [x["status"] for x in missing] ==
["missing", "missing", "missing", "applied"] and
missing[-1]["rows"] == ((6, 2, 1, 5),))
resources = resource_and_freshness_checks()
check("fresh_immutable_states_and_finally_cleanup", resources["passed"])
alphabet = (("add", 1, 0, 0, 0), ("add", 2, 0, 1, 1),
("add", 3, 1, 1, -1), ("active", 1, 1),
("active", 2, 0), ("move", 3, 0), ("drop", 2))
profiles = states = 0
statuses = {"applied": 0, "conflict": 0, "missing": 0}
for length in range(5):
for profile in itertools.product(alphabet, repeat=length):
actual = replay(profile)
expected = record_oracle(profile)
if actual != expected:
raise AssertionError(("independent_record_oracle", profile, actual, expected))
profiles += 1
states += len(actual)
for event in actual:
statuses[event["status"]] += 1
check("finite_independent_record_oracle_family_ONE_group",
profiles == 2801 and states == 10738 and sum(statuses.values()) == states)
assert len(checks) == 14 and all(type(value) is bool and value for value in checks.values())
return {"runtime": {"python": platform.python_version(),
"implementation": platform.python_implementation(),
"sqlite": sqlite3.sqlite_version},
"scope": "bounded sequential private in-memory SQL; no disk DB, network, hardware, threads, benchmark or query-plan assertion",
"units": {"channel": "synthetic identifier", "offset_mv": "authored integer mV"},
"limits": {"commands_per_replay": 6, "row_id": [1, 6], "channel": [0, 2],
"active": [0, 1], "offset_mv": [-5, 5]},
"manual_events": manual, "weakened_schema_controls": controls,
"invalid_inputs": invalid, "resource_checks": resources,
"independent_family": {"profiles": profiles, "observed_states": states,
"alphabet_size": len(alphabet), "maximum_length": 4,
"statuses": statuses, "counted_as_check_groups": 1},
"meaningful_named_groups": 14, "checks": checks}
if __name__ == "__main__":
result = run_example()
sys.stdout.buffer.write((json.dumps(result, ensure_ascii=True, indent=2) + "\n").encode("utf-8"))
قیدِ برنامه به ورودیهای معتبر همین رابط مربوط است. جدولِ سادهٔ این درس جای همهٔ محدودیتهای برنامه را نمیگیرد و مسیر SQL دلخواه در اختیار خواننده نمیگذارد. آزمایش به فایل موجود، سرویس شبکه یا حسگر وصل نمیشود. نسخهٔ واقعی Python و هستهٔ SQLite در runtime خروجی ثبت میشود؛ این شمارهها را نباید از تاریخ دسترسی به مستندات حدس زد.
۴. تغییر وضعیت، شاهد نقض و مرجع مستقل

یکتایی فقط هنگام درج اهمیت ندارد. فعالکردن نسخهای قدیمی یا انتقال نسخهٔ فعال به کانال اشغالشده نیز باید همان قاعده را رعایت کند. شاهد دستی، حفظ کامل حالت پس از درج ناسازگار را بررسی میکند؛ شاهدهای دیگر، فعالسازی و انتقال را میسنجند. حذف یا غیرفعالسازیِ نسخهٔ فعال، جایگاه را آزاد میکند. این رفتار، تضمین یک تعویض چندمرحلهایِ همزمان برای چند کاربر نیست.
مرجع مستقل هیچ SQL اجرا نمیکند. ابتدا رابطهٔ نامزد را با تغییر tupleهای ردیف میسازد، سپس همهٔ زوجهای متمایز را برای شناسهٔ تکراری یا کانال مشترکِ دو ردیف فعال مقایسه میکند. نامزد ناسازگار کنار گذاشته میشود و حالت قبلی میماند. مسیر مورد انتظار از خروجی پایگاه داده، نمایه یا تابع تغییردهندهٔ اصلی کمک نمیگیرد؛ توافق دو مسیر همچنان به قراردادهای نوشتهشده وابسته است.
خانوادهٔ متناهی از هفت فرمان مشخص، تمام دنبالههای طول صفر تا چهار را میسازد: ۲۸۰۱ دنباله و ۱۰۷۳۸ حالتِ پس از فرمان. همهٔ این موارد یک گروه از چهارده گروهِ نامدارند. شاهدهای دستی، دو کنترل NULL، قید مرکب نامناسب، ورودی نامعتبر و تازهبودن گزارشها گروههای دیگر را میسازند. برای آزمودن finally، خطای ساختگیِ خواندن snapshot عمداً تزریق و هویت همان استثنا بررسی میشود؛ این کنترل با خطای واقعی دستگاه یا شکست اجرای برنامه یکی نیست.
{
"runtime": {
"python": "3.14.5",
"implementation": "CPython",
"sqlite": "3.50.4"
},
"scope": "bounded sequential private in-memory SQL; no disk DB, network, hardware, threads, benchmark or query-plan assertion",
"units": {
"channel": "synthetic identifier",
"offset_mv": "authored integer mV"
},
"limits": {
"commands_per_replay": 6,
"row_id": [
1,
6
],
"channel": [
0,
2
],
"active": [
0,
1
],
"offset_mv": [
-5,
5
]
},
"manual_events": [
{
"command": [
"add",
1,
0,
0,
-2
],
"status": "applied",
"rows": [
[
1,
0,
0,
-2
]
]
},
{
"command": [
"add",
2,
0,
0,
1
],
"status": "applied",
"rows": [
[
1,
0,
0,
-2
],
[
2,
0,
0,
1
]
]
},
{
"command": [
"add",
3,
0,
1,
0
],
"status": "applied",
"rows": [
[
1,
0,
0,
-2
],
[
2,
0,
0,
1
],
[
3,
0,
1,
0
]
]
},
{
"command": [
"add",
4,
0,
1,
2
],
"status": "conflict",
"rows": [
[
1,
0,
0,
-2
],
[
2,
0,
0,
1
],
[
3,
0,
1,
0
]
]
},
{
"command": [
"active",
3,
0
],
"status": "applied",
"rows": [
[
1,
0,
0,
-2
],
[
2,
0,
0,
1
],
[
3,
0,
0,
0
]
]
},
{
"command": [
"active",
2,
1
],
"status": "applied",
"rows": [
[
1,
0,
0,
-2
],
[
2,
0,
1,
1
],
[
3,
0,
0,
0
]
]
}
],
"weakened_schema_controls": {
"composite_unique_rejected_second_inactive": true,
"indexed_null_key_rows": [
[
null,
1
],
[
null,
1
]
],
"predicate_null_rows_and_active": [
[
0,
null
],
[
0,
null
],
[
0,
1
]
],
"second_nonnull_active_rejected": true
},
"invalid_inputs": {
"types_ok": true,
"bounds_ok": true,
"invalid_type_cases": 28,
"invalid_bound_or_shape_cases": 15,
"connect_attempts_for_all_invalid_inputs": 0,
"generator_consumed": false
},
"resource_checks": {
"passed": true,
"tracked_connections_closed": 4,
"expected_injected_error_identity_preserved": true
},
"independent_family": {
"profiles": 2801,
"observed_states": 10738,
"alphabet_size": 7,
"maximum_length": 4,
"statuses": {
"applied": 4716,
"conflict": 982,
"missing": 5040
},
"counted_as_check_groups": 1
},
"meaningful_named_groups": 14,
"checks": {
"manual_history_and_single_active": true,
"conflicting_insert_preserves_previous_state": true,
"channels_have_independent_active_slots": true,
"deactivation_releases_slot_for_another_history_row": true,
"activating_existing_history_also_checks_uniqueness": true,
"moving_active_row_rejects_occupied_and_accepts_free_channel": true,
"deleting_active_row_preserves_history_and_releases_slot": true,
"ordinary_composite_unique_overrestricts_inactive_history": true,
"nullable_indexed_key_does_not_enforce_main_channel_rule": true,
"predicate_null_is_outside_partial_index": true,
"strict_types_and_complete_prevalidation_before_SQL": true,
"authored_bounds_shapes_and_missing_row_policy": true,
"fresh_immutable_states_and_finally_cleanup": true,
"finite_independent_record_oracle_family_ONE_group": true
}
}
منابع در ۲۱ اکتبر ۲۰۲۶ خوانده شدند. تاریخ بازنگریِ دیدهشدهٔ صفحهٔ نمایهٔ جزئی آوریل ۲۰۲۲ و صفحهٔ CREATE INDEX مه ۲۰۲۶ است؛ تاریخ انتشار اولیهٔ آنها معلوم فرض نشده است. دو سند از یک ناشر رسمیاند و تأیید مستقل دو ناشر محسوب نمیشوند. اینجا از نمایه برای الزام معنایی استفاده میکنیم؛ برخلاف آموزش نمایهٔ مرکب و پوشاننده، طرح اجرا را معیار قرار نمیدهیم و افزایش سرعتی گزارش نمیکنیم.
۵. چهار پرسش پاسخدار و مرزِ نتیجه

پرسش اول: اگر تمام نسخهها غیرفعال شوند، قید نقض شده است؟ پاسخ: خیر؛ زیرمجموعهٔ فعال تهی است و شرط حداکثر یک برقرار میماند. الزام وجود نسخهٔ منتخب، نیاز دیگری است و نباید از موفقیت UNIQUE نتیجه گرفته شود.
پرسش دوم: چرا زوج channel و active را یکتا نکنیم؟ پاسخ: چون آن قید برای هر کانال فقط یک ردیف غیرفعال هم باقی میگذارد. تاریخچهٔ دارای دو نسخهٔ غیرفعال، شاهد نقضِ همارزی دو طرح است. کلید باید کانال و شرط عضویت باید فعالبودن باشد.
پرسش سوم: پذیرفتهشدن دو ردیف دارای NULL یعنی نمایه کار نمیکند؟ پاسخ: خیر؛ ممکن است کلیدهای تهی متمایز باشند یا ردیف اصلاً وارد زیرمجموعه نشده باشد. کنترلها این علتها را تفکیک میکنند. رابط اصلی، مقدار تهی را پیش از SQL رد میکند و جدول اصلی نیز ستونهای لازم را NOT NULL دارد.
پرسش چهارم: موفقیت چهارده گروه چه تضمینی برای سامانهٔ واقعی میدهد؟ پاسخ: فقط شواهدِ همین مدلِ محدود و اجرای ثبتشده را فراهم میکند. اندازهگیری کارایی، صحت فیزیکی offset، مهاجرت دادهٔ قبلی، چنداتصالی و سیاست تعویض کالیبراسیون فعال در این آزمایش بررسی نشدهاند؛ برای آنها قرارداد و آزمون جدا لازم است.
منابع و مطالعهٔ بیشتر
- SQLite؛ تعریف نمایهٔ جزئی، زیرمجموعهٔ منتخب و یکتاییِ شرطی
- SQLite CREATE INDEX؛ کلید یکتا و رفتار NULL در یکتایی
بررسی منابع: ۲۹ مهر ۱۴۰۵. تحلیلها و پیشنهادهای اجرایی، جمعبندی نویسندهاند.

