【问题标题】:Converting JSON to a MySQL table, how should the table structure look like?将 JSON 转换为 MySQL 表,表结构应该是怎样的?
【发布时间】:2013-08-22 00:49:42
【问题描述】:

以下是JSON文件...

{
    "name":"Magic 2014 Core Set",
    "code":"M14",
    "releaseDate":"2013-07-19",
    "border":"black",
    "type":"core",
    "cards":
    [
        {
            "layout":"normal",
            "type":"Creature - Human Warrior",
            "types":["Creature"],
            "colors":["Red"],
            "multiverseid":370735,
            "name":"Academy Raider",
            "subtypes":["Human","Warrior"],
            "cmc":3,
            "rarity":"Common",
            "artist":"Karl Kopinski",
            "power":"1",
            "toughness":"1",
            "manaCost":"{2}{R}",
            "text":"Intimidate (This creature can't be blocked except by artifact creatures and/or creatures that share a color with it.)\n\nWhenever Academy Raider deals combat damage to a player, you may discard a card. If you do, draw a card.",
            "number":"124",
            "imageName":"academy raider"
        },
        {
            "layout":"normal",
            "type":"Artifact - Equipment",
            "types":["Artifact"],
            "colors":[],
            "multiverseid":370581,
            "name":"Accorder's Shield",
            "subtypes":["Equipment"],
            "cmc":0,
            "rarity":"Uncommon",
            "artist":"Alan Pollack",
            "manaCost":"{0}",
            "text":"Equipped creature gets +0/+3 and has vigilance. (Attacking doesn't cause it to tap.)\n\nEquip {3} ({3}: Attach to target creature you control. Equip only as a sorcery.)",
            "flavor":"An Auriok shield is polished to a mirror finish even on the inside, enabling its bearer to watch foes ahead and behind.",
            "number":"204",
            "imageName":"accorder's shield"
        },
        {
            "layout":"normal",
            "type":"Creature - Spirit",
            "types":["Creature"],
            "colors":["Black"],
            "multiverseid":370811,
            "name":"Accursed Spirit",
            "subtypes":["Spirit"],
            "cmc":4,
            "rarity":"Common",
            "artist":"Kev Walker",
            "power":"3",
            "toughness":"2",
            "manaCost":"{3}{B}",
            "text":"Intimidate (This creature can't be blocked except by artifact creatures and/or creatures that share a color with it.)",
            "flavor":"Many have heard the slither of dragging armor and the soft squelch of its voice. But only its victims ever meet its icy gaze.",
            "number":"83",
            "imageName":"accursed spirit"
        },
        {...},
        {...},
        {...},
    ]
}

我认为卡片数据本身会在一个表中,但我不确定如何......

"name":"Magic 2014 Core Set",
"code":"M14",
"releaseDate":"2013-07-19",
"border":"black",
"type":"core",

将与卡片数据相关联。我应该如何设计 MySQL 表以方便高效地访问?

【问题讨论】:

  • 这不是一个答案,所以它是一个评论——但 MySQL 是必需的吗?还是您认为这是存储数据的最佳方式? Postgres 和像 Couch 这样的 noSQL 解决方案都能更好地处理 JSON。
  • @Interrobang MySQL 是必需的。
  • @ØHankyPankyØ 也已提交给 dba.stackexchange.com。

标签: mysql json


【解决方案1】:

我认为您必须有 2 个表来存储此类数据。

create table tbl_card (
card_id int primary key auto_increment,
name varchar(50) not null,
code varchar(10) not null,
release_date datetime not null,
border varchar(20) not null,
type varchar(20) not null
)

create table tbl_card_detail (
card_id int not null,
type varchar not null,
....
primary key (card_id,type)
)

【讨论】:

    【解决方案2】:

    我认为您应该使用包含 (name, code, releaseDate, border, type) 的表 cardSet 和包含 cards 的另一个表,其外键引用 cardSet

    您还需要制作typecolorsubtype 与卡片桌有多对多关系的表格,因为您可以拥有一张卡片与多个typecolorsubtype

    CREATE TABLE `card` (
      `id` INT NOT NULL AUTO_INCREMENT,
      PRIMARY KEY  (`id`)
    );
    
    CREATE TABLE `type` (
      `id` INT NOT NULL AUTO_INCREMENT,
      PRIMARY KEY  (`id`)
    );
    
    CREATE TABLE `cardType` (
      `card` INT,
      `type` INT
    );
    
    CREATE TABLE `cardSet` (
      `id` INT NOT NULL AUTO_INCREMENT,
      `` INT,
      PRIMARY KEY  (`id`)
    );
    
    CREATE TABLE `color` (
      `id` INT NOT NULL AUTO_INCREMENT,
      PRIMARY KEY  (`id`)
    );
    
    CREATE TABLE `cardColor` (
      `card` INT,
      `color` INT
    );
    
    CREATE TABLE `subType` (
      `id` INT NOT NULL AUTO_INCREMENT,
      PRIMARY KEY  (`id`)
    );
    
    CREATE TABLE `cardSubType` (
      `card` INT,
      `subType` INT
    );
    
    
    
    ALTER TABLE `cardType` ADD CONSTRAINT `cardType_fk1` FOREIGN KEY (`card`) REFERENCES card(`id`);
    ALTER TABLE `cardType` ADD CONSTRAINT `cardType_fk2` FOREIGN KEY (`type`) REFERENCES type(`id`);
    ALTER TABLE `cardSet` ADD CONSTRAINT `cardSet_fk1` FOREIGN KEY (``) REFERENCES cardSet(`id`);
    
    ALTER TABLE `cardColor` ADD CONSTRAINT `cardColor_fk1` FOREIGN KEY (`card`) REFERENCES card(`id`);
    ALTER TABLE `cardColor` ADD CONSTRAINT `cardColor_fk2` FOREIGN KEY (`color`) REFERENCES color(`id`);
    
    ALTER TABLE `cardSubType` ADD CONSTRAINT `cardSubType_fk1` FOREIGN KEY (`card`) REFERENCES card(`id`);
    ALTER TABLE `cardSubType` ADD CONSTRAINT `cardSubType_fk2` FOREIGN KEY (`subType`) REFERENCES subType(`id`);
    

    【讨论】:

    • 桌子会是什么样子?你能提供一个多对多关系查询的例子吗?我以前只使用过单张桌子。我知道有一种方法可以使用多个表,但我在这方面没有太多经验。
    • @rotaercz:例如,要创建类型颜色关系,您将创建一个表 color、一个表 type 和一个表 colorTypecolorType 将有两个字段 1 个外键到colortype 的外键,你会找到代码here
    • @rotaercz:您可以查看我的更新答案,如果您有任何问题,请随时提问
    【解决方案3】:

    MySQL 是一个关系型数据库。这意味着您提出的任何解决方案都需要包含主键外键规范化。这是一个简单的教程,它将向您展示该怎么做。玩得开心!

    http://www.dreamincode.net/forums/topic/179103-relational-database-design-normalization/

    【讨论】:

    【解决方案4】:

    这是原始形式的规范化架构,您可以根据需要更改它并使用 Null、主键、外键属性、相对于您正在使用的数据库的类型来更新它

    粗体(突出显示)是表名,PK = 主键,FK = 外键,您可以根据需要进行更改

      Template (TABLE)
     1- Name
     2- Code
     3- Release Date
     4- Border
     5- Type 
     6- Id (PK)
    
     Template Cards (TABLE)
     1- Template Id  (FK) (Template Table )
     2- Card Id (FK) (Cards Table)
    
     Cards  ( Has M-M relationship with Types, Cards ,Subtypes Table)  (TABLE)
     1- layout
     2- type
     3- mutiverseid
     4- name 
     5- Card Id (PK) 
     6- Card Detail Id
    
     Cards Detail
     1- Card detail Id
     2- Card Id
     2- Object Type ( 0 = Types , 1 = Color , 2 = Subtypes )
     3- Object Id  ( This id corresponds to Types, Color , Subtypes Table with respect to Object Type )
    
     Types (TABLE)
     1- type id (PK)
     2- type Detail/Code
    
     Color (TABLE)
     1- Color id (PK)
     2- Color Detail/Code
    
     SubTypes (TABLE)
     1- Subtype id (PK)
     2- Subtype Detail/Code
    

    【讨论】:

      【解决方案5】:

      很难说应该如何构造数据,因为这可能取决于您的应用程序。但是,作为第一次切割,一些好的经验法则可能是:

      1. 单个 JSON 对象的同一“级别”的所有非数组数据都是一个表。我所说的级别是指对象的嵌套程度。因此,例如,假设 {"a": 100, "b": "hello", "c": {"x": 100, "y": "foo"}}ab 处于同一级别,而 xy 处于不同级别。
      2. 您有几个选项可用于处理不同级别的数据:
        1. “展平”嵌套,这样对于上面的示例,您将拥有一个包含 abxy 的表。
        2. 为每个嵌套级别创建新表。给定上面的示例,这是一个包含ab 的表,以及一个包含xy 的表。这两个表之间显然存在关系,它会告诉您是否如何构造链接键。有关详细信息,请参阅 https://stackoverflow.com/a/7296873/1431244
      3. 数组非常清楚地表明了一对多的关系,因此它们可以放在自己的表中,如上面链接的帖子所述。

      上面的 JSON 文件非常大,所以我不打算用所有字段构建所有表,但这里有一个示例,希望能解释粗略的想法:

      create table card_pack (
        # Primary key to uniquely identify the pack
        id integer autoincrement primary key,
        name TEXT,
        # foreign key that links to the codes table
        code_id integer,
        # etc, etc...
      );
      
      create table codes (
        # This is what the code_id field in the card_pack table refers to
        id integer autoincrement primary key,
        name CHAR(10)
      );
      
      create table cards (
        # unique key for each card
        id integer autoincrement primay key,
        # Refers to the card_pack table for the card pack
        # containing this card
        pack_id integer,
        name TEXT,
        # This should probably be a foreign key referring to a layouts table
        # which contains one row per layout
        layout TEXT,
        # etc, etc.
      )
      
      # Table with one row for every possible card color
      create table colors {
        id integer autoincrement primay key,
        name TEXT,
      )
      
      # table that defines a many-to-many relationship
      # indicating which cards are which colors, so a row with
      # card_id = 7 and color_id = 11 means that card 7 is color 11.
      # Note that another row might have card_id 7 and color_id 18
      # so that card 7 is two colors, both color 11 and color 18.
      create table cards_colors (
        card_id integer,
        color_id integer
      )
      

      在上面有很多细节缺失。例如,您可能并不真正想要所有字符串字段的通用 TEXT 类型。有些可能应该是 CHAR 和一些 VARCHAR,具体取决于字段大小、空间与性能考虑等。类似地,如果我有整数,你可能需要 bigint、mediumint 等,具体取决于你期望的值的数量等。还有索引注意事项, 外键约束等,但希望以上内容能给您正确的想法并提供足够的信息来开始。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-09
        • 2023-03-31
        • 2011-10-29
        • 1970-01-01
        相关资源
        最近更新 更多