You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native中Realm数据库如何实现1:n关系两张表关联

Realm 一对多表关联实现方案

你当前用int类型存city_id手动做外键的写法不是Realm推荐的关联方式,Realm提供了原生的对象引用能力,直接定义关联关系即可实现1:n映射,不需要手动维护外键,查询和关联操作性能更高,也不会出现数据不一致问题。


第一步:修改两个Schema定义

核心改动点共2处:

  • 在「多」端(活动表Detail),把原来的int类型city_id替换为Town类型的对象引用,标记活动所属城市
  • 在「一」端(城市表Town),通过反向链接(backlink)属性自动关联该城市下的所有活动,不需要手动维护列表数据

修改后的完整Schema代码如下:

const CitySchema = {
  name: "Town",
  properties: {
    _id: "int",       // 主键
    name: "string",   // 城市名称
    region: "string", // 所属区域
    street: "string", // 街道地址
    city: "string",   // 邮编+城市名
    phone: "int",     // 联系电话
    ico: "int",       // 机构编号
    dic: "string",    // 税号
    logo: "string",   // logo地址
    lat: "double",    // 纬度
    lng: "double",    // 经度
    // 新增:反向关联所有归属当前城市的活动,不需要手动赋值
    events: {
      type: "linkingObjects",
      objectType: "Detail",
      property: "belongCity"
    }
  },
  primaryKey: "_id",
};

const EventSchema = {
  name: "Detail",
  properties: {
    _id: "int",       // 主键
    // 替换原来的city_id: "int",直接关联所属城市对象
    belongCity: "Town",
    eventName: "string",   // 活动名称
    eventDescription: "string", // 活动描述
  },
  primaryKey: "_id",
};

第二步:初始化Realm

如果是首次使用没有历史数据,直接传入schema即可;如果已有存量历史数据,需要增加版本号做轻量迁移,把旧的city_id映射为新的对象引用:

(async () => {
  const realm = await Realm.open({
    path: "myrealm",
    schema: [CitySchema, EventSchema],
    // 有旧数据的话打开下面的版本配置,执行迁移
    // schemaVersion: 2,
    // onMigration: (oldRealm, newRealm) => {
    //   if (oldRealm.schemaVersion < 2) {
    //     const oldEvents = oldRealm.objects("Detail");
    //     const newEvents = newRealm.objects("Detail");
    //     for (let i = 0; i < oldEvents.length; i++) {
    //       const oldEvent = oldEvents[i];
    //       const newEvent = newEvents[i];
    //       // 用原来存的city_id找到对应城市对象,赋值给关联字段
    //       newEvent.belongCity = newRealm.objectForPrimaryKey("Town", oldEvent.city_id);
    //     }
    //   }
    // }
  });
})();

常用关联操作示例

  • 新建城市并绑定活动:
realm.write(() => {
  // 先创建城市
  const town = realm.create("Town", {
    _id: 1,
    name: "Obec Jalubí",
    region: "Zlínský kraj",
    street: "Jalub 1",
    city: "123 45 Jalubí",
    phone: 999999999,
    ico: 123456789,
    dic: "CZ123456789",
    logo: "https://www.jalubi.eu/skins/jalubi.eu_lego2/images/crest.png",
    lat: 50.1163,
    lng: 18.4279
  });
  // 创建活动时直接绑定所属城市
  realm.create("Detail", {
    _id: 1,
    belongCity: town,
    eventName: "Balloon popping",
    eventDescription: "This event is about...."
  })
})
  • 查询某城市下所有活动:直接取城市的events属性即可,这是Realm自动维护的活动列表
const targetTown = realm.objectForPrimaryKey("Town", 1);
const townEvents = targetTown.events; // 拿到该城市下所有关联的活动
  • 查询某活动所属城市:直接取活动的belongCity属性即可
const targetEvent = realm.objectForPrimaryKey("Detail", 1);
const eventBelongTown = targetEvent.belongCity; // 拿到活动归属的城市对象

注意事项

  • 不要同时保留旧的city_id字段和对象关联字段,避免出现数据不一致
  • 用linkingObjects定义的反向关联属性是只读的,不需要手动往events列表里push活动,只要给活动设置了belongCity属性,对应城市的events列表会自动更新
  • 如果业务允许活动暂时不绑定城市,可以把belongCity的类型改成"Town?"标记为可选字段

内容的提问来源于stack exchange,提问作者Tomáš Gabriel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 20:48:35