网没断的时候,根本不用挑
下面这段在网没断的情况下按两种策略各读一次。打出两种各读到什么(用 / 隔开)。
同一份数据(3 个人、每人 1 个地址、一共 5 张订单)摆成五种样子 USERS/ADDRS/ORDERS 关系:三张表,靠 id 对上 DOCS 文档:一个人一个文档,地址和订单**嵌在里面** KV 键值:只能按键取,取回来是一整块 WIDE 宽列:一个行键挂一族列,**每行的列可以不一样** GRAPH 图:谁认识谁 现成的工具函数 rel_read(uid) / doc_read(uid) → (碰了几处, 拿到几张订单) rel_move(uid, 城市) / doc_move(uid, 城市) → 改了几处 hops(谁, 走几步) → 走这么多步能够到哪些人(按名字排好) cap(keep, broken) → 网断了时读一个刚改过的值:(读到什么, 拒绝了几次)
# ── 摆法一:关系模型(三张表,靠 id 对上)────────────────────────────
USERS = [{"id": 1, "name": "甲", "aid": 11},
{"id": 2, "name": "乙", "aid": 12},
{"id": 3, "name": "丙", "aid": 13}]
ADDRS = [{"id": 11, "city": "杭州"},
{"id": 12, "city": "苏州"},
{"id": 13, "city": "杭州"}]
ORDERS = [{"id": 101, "uid": 1, "amt": 30}, {"id": 102, "uid": 1, "amt": 50},
{"id": 103, "uid": 1, "amt": 20}, {"id": 104, "uid": 2, "amt": 40},
{"id": 105, "uid": 3, "amt": 60}]
# ── 摆法二:文档模型(一个人一个文档,地址和订单都嵌在里面)──────────
DOCS = [
{"id": 1, "name": "甲", "addr": {"city": "杭州"},
"orders": [{"id": 101, "amt": 30, "city": "杭州"},
{"id": 102, "amt": 50, "city": "杭州"},
{"id": 103, "amt": 20, "city": "杭州"}]},
{"id": 2, "name": "乙", "addr": {"city": "苏州"},
"orders": [{"id": 104, "amt": 40, "city": "苏州"}]},
{"id": 3, "name": "丙", "addr": {"city": "杭州"},
"orders": [{"id": 105, "amt": 60, "city": "杭州"}]},
]
# ── 摆法三:键值(只能按键取,取回来是一整块)────────────────────────
KV = {"user:1": "甲|杭州", "user:2": "乙|苏州", "user:3": "丙|杭州"}
# ── 摆法四:宽列(一个行键下面挂着一族列,每行的列可以不一样)────────
WIDE = {
"u1": {"name": "甲", "city": "杭州", "vip": "1", "note": "老客"},
"u2": {"name": "乙", "city": "苏州"},
"u3": {"name": "丙", "city": "杭州", "vip": "0"},
}
# ── 摆法五:图(谁认识谁)────────────────────────────────────────────
GRAPH = {"甲": ["乙", "丙"], "乙": ["丁"], "丙": ["丁", "戊"],
"丁": ["己"], "戊": [], "己": []}
def rel_read(uid):
"""关系模型取一个人的全部信息:碰了几张表,拿到几张订单。"""
touched = 0
u = None
touched = touched + 1
for x in USERS:
if x["id"] == uid:
u = x
touched = touched + 1
city = None
for a in ADDRS:
if a["id"] == u["aid"]:
city = a["city"]
touched = touched + 1
os_ = [o for o in ORDERS if o["uid"] == uid]
return touched, len(os_)
def doc_read(uid):
"""文档模型取同一个人:碰了几处,拿到几张订单。"""
for d in DOCS:
if d["id"] == uid:
return 1, len(d["orders"])
return 1, 0
def rel_move(uid, city):
"""关系模型给一个人换城市:改了几处。"""
n = 0
for x in USERS:
if x["id"] == uid:
for a in ADDRS:
if a["id"] == x["aid"]:
a["city"] = city
n = n + 1
return n
def doc_move(uid, city):
"""文档模型给同一个人换城市:改了几处(订单里也各存了一份)。"""
n = 0
for d in DOCS:
if d["id"] == uid:
d["addr"]["city"] = city
n = n + 1
for o in d["orders"]:
o["city"] = city
n = n + 1
return n
def hops(who, depth):
"""从 who 出发走 depth 步,能够到哪些人(不含自己)。按名字排好。"""
seen = {who}
front = [who]
for i in range(depth):
nxt = []
for p in front:
for q in GRAPH.get(p, []):
if q not in seen:
seen.add(q)
nxt.append(q)
front = nxt
return sorted(seen - {who})
def cap(keep, broken):
"""网络断了的时候,另一半机器上读一个刚改过的值会怎样。
keep="一致" → 宁可不给答案;keep="可用" → 给一个可能是旧的答案。
返回 (读到什么, 拒绝了几次)。"""
if not broken:
return "新值", 0
if keep == "一致":
return "拒绝", 1
return "旧值", 0
a, _ = cap("一致", False)
b, _ = cap("可用", False)
print(a + "/" + b)
全部评论