自己写:找出读写比例的那个分界点

👁️ 0 人浏览 💬 0 人评论 ❤️ 添加收藏

把 TODO 补完:取 N 次、改 1 次。在 1 / 2 / 3 / 4 里找出最小的那个 N,让文档模型碰的处数少于关系模型。打出那个 N。

同一份数据(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
r1, _ = rel_read(1)
d1, _ = doc_read(1)
r2 = rel_move(1, "南京")
d2 = doc_move(1, "南京")
# TODO:在 1/2/3/4 里找出最小的、让文档更省的那个 N
print(0)
提交你的答案
请登录后提交答案。
去登录
代码编辑器
Ctrl + Enter 运行
本次输入:
输出:

                        
👩‍🏫
AI
💬 题目评论

全部评论