2011-12-11 2 views
2

У меня есть некоторые фундаментальные вопросы проектирования БД, и я хотел, чтобы они были очищены до того, как я пройду и вычеркиваю все отношения БД.Вопросы по MySQL DB Design

Вопрос 1

У меня есть две таблицы, где первый будет содержать 1 экземпляр второго. Я буду использовать структуру сущностей и хотел бы получить доступ table1 от table2 и table2 от table1.

Моя идея состояла в том, чтобы иметь внешний ключ от table1 к table2, а другой из table2 в table1. Добавление ссылки с table1 на table2 похоже на работу. Однако, когда я пытаюсь добавить вторую ссылку (от table2 до table1), MySQL Workbench добавляет две ссылки вместо одной. Я думаю, что я делаю что-то неправильно, так как я понимаю, что он должен добавить только одну ссылку. Является ли мой дизайн неправильным, или мне нужно просто удалить вторую добавленную ссылку?

mysql workbench diagram

Вопрос 2

Далее, я пытаюсь реализовать таблицы объединения. Экземпляр table1 может иметь множество экземпляров table2 и наоборот, поэтому таблица соединений, по-видимому, является необходимой структурой для достижения этой цели. MySQL позволяет мне создать либо Identifying Relationship, либо Non-Identifying Relationship, и я не уверен, что использовать. Есть идеи?

enter image description here

Если больше требуется разъяснение, пожалуйста, дайте мне знать.

+2

Что вы пытаетесь моделировать - мебель? –

+0

Два изображения представляют собой два разных набора таблиц. В первом случае я пытаюсь моделировать слово, которое может иметь один «образ», связанный с ним, и одно «изображение» может принадлежать многим «словам». Во втором случае «пользователь» может иметь много слов, а «слово» может принадлежать многим «пользователям». – JesseBuesking

+0

О вашем втором вопросе: http://stackoverflow.com/questions/762937/whats-the-difference-between-identifying-and-non-identifying-relationships –

ответ

1

Как указано ypercube и JesseB Я думаю, что все, что вам нужно, это отношение 1..n.

С Entity Framework 4.1 (и POCO Code First) все, что вам нужно, это карта, которая декларирует эти отношения, как

this.HasRequired(t => t.Image) 
    .WithMany(t => t.Words) 
    .HasForeignKey(d => d.ImageId); 

Пожалуйста, найдите здесь полный и рабочий код. При запуске он создаст базу данных со всеми необходимыми внешними ключами. Вы увидите, что единственный внешний ключ, который вам нужен, - image_id в таблице words. Entity Framework может вставлять коллекцию Word s в любой объект Image, не полагаясь на какой-либо дополнительный внешний ключ.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using WordAndImages.Entities; 
using System.Data.Entity; 
using System.Data.Entity.ModelConfiguration; 

namespace WordAndImages 
{ 

    public class Word 
    { 
     public int Id { get; set; } 
     public int ImageId { get; set; } 
     public virtual Image Image { get; set; } 
     public string Value { get; set; } 
    } 

    public class Image 
    { 
     public int Id { get; set; } 
     public virtual List<Word> Words { get; set; } 
     public string Value { get; set; } 
     public Image() 
     { 
      Words = new List<Word>(); 
     } 
    } 


    public class Context : DbContext 
    { 
     static Context() 
     { 
      Database.SetInitializer<Context>(null); 
     } 

     public DbSet<Word> Words { get; set; } 
     public DbSet<Image> Images { get; set; } 

     protected override void OnModelCreating(DbModelBuilder modelBuilder) 
     { 
      modelBuilder.Configurations.Add(new WordsMap()); 
     } 
    } 

    public class WordsMap : EntityTypeConfiguration<Word> 
    { 
     public WordsMap() 
     { 
      this.HasRequired(t => t.Image) 
       .WithMany(t => t.Words) 
       .HasForeignKey(d => d.ImageId); 
     } 
    } 


    class Program 
    { 
     static void Main(string[] args) 
     { 

      #region Saving a Word with an Image 

      var context = new Context(); 
      context.Database.Delete(); 
      context.Database.CreateIfNotExists(); 

      var word = new Word(); 
      word.Value = "I'm a word"; 

      var image = new Image(); 
      image.Value = "I'm an image"; 

      word.Image = image; 

      context.Words.Add(word); 
      context.SaveChanges(); 
      #endregion 

      #region Accessing an Image from a Word and viceversa 

      var context2 = new Context(); 

      var recovered_word = context2.Words.Where(w => w.Value == "I'm a word").FirstOrDefault(); 
      Console.WriteLine(string.Format("I'm the word '{0}' and my image is '{1}'", word.Value, word.Image.Value)); 

      var recovered_image = context2.Images.Where(w => w.Value == "I'm an image").FirstOrDefault(); 
      Console.WriteLine(string.Format("I'm the image '{0}' and one of my images is '{1}'", recovered_image.Value, recovered_image.Words.First().Value)); 

      Console.ReadLine(); 
      #endregion 
     } 
    } 
} 

Для many-to-many отношений, просто использовать карту как

this.HasMany(a => a.Words) 
    .WithMany(z => z.Images) 
    .Map(m => 
    m.ToTable("Images_Words").MapLeftKey("Word_id").MapRightKey("Image_id")); 

и изменять классы как следовать

public class Word 
{ 
    public int Id { get; set; } 
    public virtual List<Image> Images { get; set; } 
    public string Value { get; set; } 
    public Word() 
    { 
     Images = new List<Image>(); 
    } 
} 

public class Image 
{ 
    public int Id { get; set; } 
    public virtual List<Word> Words { get; set; } 
    public string Value { get; set; } 
    public Image() 
    { 
     Words = new List<Word>(); 
    } 
} 

Если не работает со старыми базами данных, я люблю проектирование домена объекты первого , и пусть ORM создает таблицы и внешние ключи.

В случае, если вы предпочитаете начинать с базы данных, учитывайте Extension Entity Framework Power Tools CTP1, которую вы можете загрузить из Extension Manager: он может создавать классы POCO из базы данных.