代码之家  ›  专栏  ›  技术社区  ›  Hildy

具有多个外键的SQL关系

  •  0
  • Hildy  · 技术社区  · 6 年前

    我正在为我的定制吉他公司建立一个网站,我刚刚意识到数据库的工作方式有一些我无法理解的地方——或者我想得太多了,让自己困惑。

    有两个表需要相互关联:一个 Artists 桌子和桌子 Projects 桌子这个 artists 表中存储了有关个别艺术家和艺术家的信息 项目 表存储有关乐队/项目的信息。

    创建 艺术家 表,并将其主键用作 项目 桌子如果一位艺术家参与了多个项目,那么这种安排就没有问题。然而,我想到的是,一个项目也完全有可能与多个艺术家关联。

    我知道有一个 artist_id 字段作为 项目 表,如果它有多个值(非原子);但我不确定我还能如何做到这一点。

    了解用例也可能有所帮助:

    我正在构建Django REST后端,它将被一个有角度的前端占用。有一个包含艺术家个人资料的页面,Angular使用 *ngFor .因此,添加到 DOM 具有 *ngFor 将展示艺术家的姓名、简历和图片;与艺术家关联的项目将添加到 多姆 通过内部ngFor循环。

    以下是角度方面的数据结构:

    import {ArtistSocialMediaModel} from './artist-social-media.model';
    
    export class ArtistProfilesModel {
      public artist_name: string;
      public artist_image: string;
      // the second string is a range of active dates for a given project
      // which I will convert to a string in Django before serializing
      public projects: Array<[string, string]>;
      public description: string;
      public band_website: string;
      public social_media: ArtistSocialMediaModel[];
    
      constructor(name: string, image: string, projects,
              description: string, website: string, social) {
    
    
        this.artist_name = name;
        this.artist_image = image;
        this.projects = projects;
        this.description = description;
        this.band_website = website;
        this.social_media = social;
      }
    
    }
    

    这是你在上面看到的社交媒体模式,但这将是一种与客户的一对一关系 Artists_Social 表:

    export class ArtistSocialMediaModel {
      public facebook: string;
      public twitter: string;
      public instagram: string;
    
      constructor(facebook: string, twitter: string, instagram: string) {
        this.facebook = facebook;
        this.twitter = twitter;
        this.instagram = instagram;
      }
    
    }
    

    这是显示数据的模板:

        <div *ngFor="let profile of artistProfiles; let i = index"
         class="profiles-div">
    
        <div *ngIf="resolveIndex(i) === 'left'; then left else right">ignored</div>
    
        <ng-template #left>
          <div class="row">
    
          <div class="col-6 col-md-5">
    
            <img [src]="profile.artist_image"
                 [alt]="profile.artist_name"
                 class="img-thumbnail img-fluid"
                 [ngStyle]="{ 'float': resolveIndex(i)}">
    
            <h1 class="artists-jumbo-header"
                [ngStyle]="{ 'text-align': resolveIndex(i)}">
              Projects:
            </h1>
            <p *ngFor="let project of profile.projects"
               [ngStyle]="{ 'text-align': resolveIndex(i)}"
               class="artists-p">
              {{project[0] + ": " + project[1]}}
            </p>
    
            <h1 class="artists-jumbo-header"
                [ngStyle]="{ 'text-align': resolveIndex(i)}">
              Website:
            </h1>
            <a href="https:{{profile.band_website}}"
               target="_blank">
              <p [ngStyle]="{ 'text-align': resolveIndex(i)}"
                 class="artists-p">
                {{profile.band_website}}
              </p>
            </a>
    
            <h1 class="artists-jumbo-header"
                [ngStyle]="{ 'text-align': resolveIndex(i)}">
              Social Media:
            </h1>
            <a href="https://{{profile.social_media['facebook']}}"
               target="_blank">
              <p [ngStyle]="{ 'text-align': resolveIndex(i)}"
                 class="artists-p">{{profile.social_media['facebook']}}</p>
            </a>
    
            <a href="https://{{profile.social_media['twitter']}}"
               target="_blank">
              <p [ngStyle]="{ 'text-align': resolveIndex(i)}"
                 class="artists-p">{{profile.social_media['twitter']}}</p>
            </a>
    
            <a href="https://{{profile.social_media['instagram']}}"
               target="_blank">
              <p [ngStyle]="{ 'text-align': resolveIndex(i)}"
                 class="artists-p">
                {{profile.social_media['instagram']}}</p>
            </a>
          </div>
    
          <div class="col-6 col-md-7">
            <h1 class="artists-jumbo-header">{{ profile.artist_name }}
            </h1>
            <br>
            <p class="artists-p">{{ profile.description }}</p>
          </div>
        </div>
       </ng-template>
    
       <ng-template #right>
        <div class="row ng-template-right">
          <div class="col-6 col-md-7">
            <h1 class="artists-jumbo-header">{{ profile.artist_name }}
            </h1>
            <br>
            <p class="artists-p">{{ profile.description }}</p>
          </div>
          <div class="col-6 col-md-5">
            <img [src]="profile.artist_image"
                 [alt]="profile.artist_name"
                 class="img-thumbnail"
                 [ngStyle]="{ 'float': resolveIndex(i)}">
    
            <div class="container">
              <h1 class="artists-jumbo-header"
                  [ngStyle]="{ 'text-align': resolveIndex(i)}">
                Projects:
              </h1>
              <p *ngFor="let project of profile.projects"
                 [ngStyle]="{ 'text-align': resolveIndex(i)}"
                 class="artists-p">
                {{project[0] + ": " + project[1]}}
              </p>
    
              <h1 class="artists-jumbo-header"
                  [ngStyle]="{ 'text-align': resolveIndex(i)}">
                Website:
              </h1>
              <a href="https:{{profile.band_website}}"
                 target="_blank">
                <p [ngStyle]="{ 'text-align': resolveIndex(i)}"
                   class="artists-p">
                  {{profile.band_website}}
                </p>
              </a>
    
              <h1 class="artists-jumbo-header"
                  [ngStyle]="{ 'text-align': resolveIndex(i)}">
                Social Media:
              </h1>
              <a href="https://{{profile.social_media['facebook']}}"
                 target="_blank">
                <p [ngStyle]="{ 'text-align': resolveIndex(i)}"
                   class="artists-p">{{profile.social_media['facebook']}}</p>
              </a>
    
              <a href="https://{{profile.social_media['twitter']}}"
                 target="_blank">
                <p [ngStyle]="{ 'text-align': resolveIndex(i)}"
                   class="artists-p">{{profile.social_media['twitter']}}</p>
              </a>
    
              <a href="https://{{profile.social_media['instagram']}}"
                 target="_blank">
                <p [ngStyle]="{ 'text-align': resolveIndex(i)}"
                   class="artists-p">
                  {{profile.social_media['instagram']}}</p>
              </a>
            </div>
    
          </div>
        </div>
      </ng-template>
    
      <hr>
    
    </div>
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   Michael Gunter    6 年前

    我对Django一无所知,但你问的是一种多对多的关系。在大多数数据库系统中,多对多是通过第三个表实现的,该表带有指向所链接表的外键。一些数据库系统允许您将数组存储为行的成员,可以用于此目的。然而,这是一件罕见的事情(通常只出现在分层数据库中)。第三种方法是最广泛适用的。

    在你的情况下,你的桌子看起来像这样。请注意 Artist_Projects 表是一个复合键——它是 结合体 属于 artist_id project_id 这是主键。但每个字段都是一个单独表的外键。

    +----------------+      +----------------------+      
    | Artists        |      | Artist_Projects      |      +-----------------+
    +----------------+      +----------------------+      | Projects        |
    | artist_id (PK) | <--- | artist_id  (PK) (FK) |      +-----------------+
    +----------------+      | project_id (PK) (FK) | ---> | project_id (PK) |
                            +----------------------+      +-----------------+