2017-01-10 4 views
-1

Я действительно смущен. Я просто не могу найти руководство, предназначенное для noobs или манекенов, чтобы понять, все, что я получаю, продвинуты или, по крайней мере, узнали технические вещи, которые я забыл. (Не очень большой в базу данных, когда я еще учился)База данных 3 типа пользователей

rought outline

Так я разместил изображение грубой схемы я сделал, я был у него в течение нескольких часов, но мой undecisiveness не идет куда-нибудь, я в два раза Угадайте меня каждый раз, когда я чувствую себя im на правильном пути.

В любом случае, как мне проектировать таблицы?

Скажем, например, существует 3 типа учетной записи. 1 для нормального, 2 для тренеров и 3 для гимнастов.

Я использую таблицу учетных записей, чтобы получить уровень доступа к учетным записям. Поэтому я действительно смущен. Я уверен, что все таблицы должны иметь первичный ключ. поэтому я решил, что у каждого есть id на всей таблице.

Подобно userid, trainerid, gymid.

Итак, как я могу их нанести на стол учетной записи? я добавляю все 3 как FK? что, если бы это был обычный пользователь, тогда тренер (FK) и фуникул (FK) были бы пустыми, это даже приемлемо для FK, чтобы он был нулевым?

В таблице счетов также есть учетная запись (PK), даже не уверенная в том, что она вообще полезна, или потому, что мне нужно только проверять таблицу уровня доступа в таблице учетных записей (я, вероятно, узнаю, когда я глубоко вовлечен в на данный момент я просто не могу видеть использование ПК в таблице учетных записей, за исключением того факта, что вам нужна ПК для каждой таблицы).

Так что я думаю, должен ли я просто использовать имя пользователя в качестве внешнего ключа? но может ли обычный уникальный cols быть внешним ключом? или они должны быть установлены на первичные ключи?

Кроме того, в связи с 3-мя типами учетных записей у каждого из них есть профиль, должен ли я создать другую таблицу, которая соединяется с ними с именем profile? (По одному для каждого типа пользователей, например user_profile, trainer_profile, gym_profile).

+0

У вас здесь много проблем. Первый - базовый [дизайн базы данных] (http://sqlmag.com/database-performance-tuning/sql-design-why-you-need-database-normalization) и выяснение ваших объектов. Во-вторых, у вас есть проблема безопасности. У .NET есть некоторые хорошие встроенные функции, такие как [Identity] (https://www.asp.net/identity/overview/getting-started/introduction-to-aspnet-identity), которые могут помочь. –

+0

Я просто делаю проект для себя и не ставил их в Интернете. Если проблемы с безопасностью связаны с хэшированными паролями, а что нет, я планировал это, но я еще не сделал этого, поскольку я больше фокусируюсь на получении более четкого изображения, а затем реализую его после этого, я позабочусь о других нюансах, таких как безопасности и т. д. Мне просто нужна грубая форма, в которой я могу полировать. – john

+0

ОК, начните со своих основных объектов: учетная запись, тренажерный зал, пользователь, тренер. Первичные ключи зависят от вас - я предпочитаю [суррогатные ключи] (http://stackoverflow.com/questions/20052799/surrogate-key-vs-natural-key-for-ef), но вы можете использовать естественные ключи, такие как UserName если хочешь. Затем сделайте связь между этими таблицами, и EF выполнит фоновое задание. –

ответ

0

Возможно, одна из проблем заключается в том, что вы сразу начинаете думать о таблицах и идентификаторах и внешних ключах и т. Д. Обычно гораздо проще, если вы думаете об объектах и ​​их отношении друг к другу.

Немного сложно прочитать вашу фотографию. Из текста, который я собираю, у вас есть понятие учетной записи, и, судя по всему, существует три типа счетов: обычные, тренеры и владельцы спортзалов. Есть ли разница между этими счетами? У владельцев спортзалов есть свойства, которых нет у обычных пользователей? или это просто какая-то идентификация.

С вашего рисунка кажется, что у обычного пользователя есть имя пользователя, пароль и уровень доступа. У тренеров также есть эти свойства?

Если это так, то в нормальном объектно-ориентированном дизайне вы бы сказали, что это агрегация: тренеры, обычные люди и владельцы спортзалов все имеют имя пользователя, пароль и уровень доступа. агрегация также довольно часто называется композицией. Существует небольшая разница, но для этого обсуждения это не важно.

Вместо агрегации/составления (объект, который имеет учетную запись) вы также можете думать о наследовании: объект - это учетная запись: учетные записи тренеров, учетные записи владельца тренажерного зала и обычные учетные записи - это объекты, которые являются разными видами учетных записей, с имя пользователя, пароль и уровень доступа.

В этом примере нет большой разницы между агрегацией (у тренера есть учетная запись) или наследованием (учетная запись тренера - это учетная запись). Обычно совет должен поддерживать агрегацию над наследованием enter link description here

Помните: если единственная разница между тремя учетными записями - это значение свойства, а затем подумайте о том, чтобы сделать их одинаковыми, со свойством AccountType, который дает вам информацию о будь то обычная учетная запись, учетная запись владельца тренажерного зала или счет тренера.

Если разница между этими тремя является уровнем доступа, то не создавайте тип учетной записи. Уровень доступа будет служить типом учетной записи.

До сих пор я говорю только о объектно-ориентированном дизайне. Как только вы разработали свои объекты, вы можете подумать о том, чтобы поместить их в базу данных.

Предположим, что тренер, владелец тренажерного зала и нормальные люди действительно разные вещи, с разными свойствами. Ваш класс будет выглядеть так:

public enum AccessLevel 
{ 
    None, 
    ..., 
    FullAccess, 
} 

public class Account 
{ 
    public string UserName {get; set;} 
    public string Password {get; set;} 
    public AccessLevel AccessLevel {get; set;} 
} 

public class Trainer 
{ 
    public .. some trainer properties {get; set;} 
    // a trainer has an account 
    public Account Account {get; set;} 
} 

public class GymOwner 
{ 
    public ... some gym owner properties {get; set;} 
    public Account Account {get; set;} 
} 

Если ваш дизайн будет, как это, вы бы увидели, что по крайней мере вы бы таблицу владельца тренажерного зала и стол тренера. Но что делать со Счета.

Одним из решений было бы разместить учетную запись в отдельной таблице и добавить что-то к тренеру и владельцу тренажерного зала, чтобы, если у вас есть тренер, вы знаете, какой элемент в таблице учета принадлежит данному конкретному тренеру.

Этот метод обычно не используется в этой конструкции. Если объект A и объект B имеют отношение один к одному: один A принадлежит одному B, а один B принадлежит одному A, то на самом деле их можно поместить в одну таблицу. Если вы используете инфраструктуру сущности и определили классы выше, свойства учетной записи будут добавляться в виде столбцов в таблицу тренеров и в виде столбцов в таблицу владельца тренажерного зала. Преимущество в том, что получение информации о тренере происходит быстрее, так как это предполагает доступ только к одной таблице.

О главных ключах. Каждый элемент в каждой таблице должен иметь ровно один первичный ключ. Это свойство, которое идентифицирует объект. Если у вас есть ключ, у вас очень быстрый доступ ко всем другим свойствам. Чтобы облегчить вам понимание роли учетной записи, я оставил Id в своем исходном коде.

Но теперь, когда мы решили, что было бы лучше, чтобы владельцы Тренеры и Тренажерщики имели учетную запись, там было бы два: Тренеры и GymOwners. Это единственные элементы, которые имеют первичный ключ. Занятия будут следующими:

public class Account 
{ 
    public string UserName {get; set;} 
    public string Password {get; set;} 
    public AccessLevel AccessLevel {get; set;} 
} 

public class Trainer 
{ 
    public int Id {get; set;} 
    public .. some trainer properties {get; set;} 
    // a trainer has an account 
    public Account Account {get; set;} 
} 

public class GymOwner 
{ 
    public int Id {get; set;} 
    public ... some gym owner properties {get; set;} 
    public Account Account {get; set;} 
} 

Обратите внимание, что для учетной записи нет таблицы, поэтому учетной записи не нужен ключ.

Так что, когда вам нужен внешний ключ

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

В терминах базы данных это называется отношением «один ко многим»: у одного тренера есть много учетных записей.

В рамках сущности классы будут, как:

public class Account 
{ 
    public int Id {Get; set;} 
    public int TrainerId {get; set;} 

    public string UserName {get; set;} 
    public string Password {get; set;} 
    public AccessLevel AccessLevel {get; set;} 
} 

public class Trainer 
{ 
    public int Id {get; set;} 
    public .. some trainer properties {get; set;} 
    // a trainer has an account 
    public virtual ICollection<Account> Accounts {get; set;} 
} 

public class MyDbContext : DbContext 
{ 
    public DbSet<Trainer> Trainers {get; set;} 
    public DbSet<Account> Accounts {get; set;} 
} 

Обратите внимание, что из-за счета имеют свою собственную таблицу он получил первичный ключ. Кроме того, он также получил внешний ключ в собственности TrainerId.

Я также добавил класс, полученный из DbContext, для доступа к таблицам. Пока не знаю, что у меня есть только таблицы с тренерами и таблицами со счетами. Каждая таблица называется DbSet, тип DbSet сообщает структуру сущности о столбцах в таблице.

Поскольку Trainer имеет виртуальный ICollection of Accounts, инфраструктура сущности знает, что между тренером и учетной записью существует отношение «один ко многим», а из-за наследования TrainerId структура сущности знает, что TrainerId является внешним ключом к первичному ключа трейнера, к которому принадлежит учетная запись.

Так что если у вас есть идентификатор тренера, вы получите все аккаунты этого тренера, используя следующие операторы Linq:

int trainerId = GetMyTrainerId(); 
IEnumerable<Account> accountsOfTrainer = dbContext.Accounts 
    .Where(account => account.TrainerId == trainerId); 

Из коллекции счетов, принять все записи, в которых свойство TrainerId равняется trainerId

Итак, теперь вы знаете, как создать первичный ключ и указать на него внешний ключ.

А как насчет владельцев тренажерных залов? Если владелец тренажерного зала имеет только одну учетную запись, просто позвольте ей иметь один аккаунт (состав). Но что, если ваш владелец спортзал также имеет коллекцию учетных записей.

Если вы просто добавили учетные записи владельца тренажерного зала в таблицу счетов, то у вас возникают проблемы. К какому идентификатору относится внешний ключ? К первичному ключу в таблице Тренера или в таблице владельцев тренажеров?

Самый безопасный способ - создать GymOwnersAccount и TrainingersAccount. У каждого будет своя таблица с внешним ключом. У GymOwnersAccount будет внешний ключ к таблице GymOwners, а у TrainersAccount будет внешний ключ для таблицы тренеров.

Здесь вы также можете принять решение о том, что учетная запись GymOwners должна иметь учетную запись, но кажется более естественным сказать, что учетная запись GymOwners является особым типом учетной записи и, следовательно, происходит из учетной записи.

public class Account 
{ 
    public string UserName {get; set;} 
    public string Password {get; set;} 
    public AccessLevel AccessLevel {get; set;} 
} 

public class GymOwnerAccount : Account 
{ 
    public int Id {get; set;} 
    public int GymOwnerId {get; set;} 
} 
public class TrainerAccount : Account 
{ 
    public int Id {get; set;} 
    public int TrainerId {get; set;} 
} 

public class Trainer 
{ 
    public int Id {get; set;} 
    public .. some trainer properties {get; set;} 
    // a trainer has an account 
    public virtual ICollection<Account> Accounts {get; set;} 
} 

public class GymOwner 
{ 
    public int Id {get; set;} 
    public ... some gym owner properties {get; set;} 
    public virtual ICollection<Account> Accounts {get; set;} 
} 

public class MyDbContext : DbContext 
{ 
    public DbSet<Trainer> Trainers {get; set;} 
    public DbSet<Account> GymOwnerAccounts {get; set;} 
    public DbSet<Account> TrainerAccounts {get; set;} 
} 

Есть и другие решения можно, например, дать каждому счету два внешних ключей, один для владельцев тренажерного зала и один для инструкторов, где вы всегда должны установить один внешний ключ к 0. Легко видеть, что это может приводят к проблемам технического обслуживания, в то время как это не дает вам никаких преимуществ, поэтому я бы посоветовал придерживаться отдельных таблиц для GymOwnerAccounts и TrainerAccounts.

Теперь, когда я вошел в область наследования в базе данных, есть множество элементов, которые вы можете настроить. Статья, которая помогла мне понять концепцию сущности, а также то, как классы, наследование, состав передается в базы данных, - Entity Framework Code First

+0

Это было где-то рядом, мой мозг просто пожарил, мне, возможно, придется спать после всего. Я просто хотел бы уточнить, что касается 3 типов счетов. Я планировал сделать проект, в котором вы можете найти спортивные залы в Интернете, когда вы найдете тренажерный зал онлайн, вы зачисляетесь в эти спортивные залы (онлайн или irl оплата) после регистрации вы можете выбрать программы, в которых есть тренеры на выбор и из одного программа к следующему, тренер будет отслеживать ваши успехи, и если вы закончите, система порекомендует дальнейшие программы. как дерево навыков. В любом случае каждый пользователь получает доступ к функциям diff. – john

+0

Пользователи, имеющие профили данных, а также тренажерный зал и тренажеры. Вот почему я смущен. Я просто не могу окутать голову в разработку грубой схемы моей базы данных, даже без специфики, если у меня есть только грубая схема atleast id, которая имеет направление кода. – john

+0

Итак, у вас есть классный зал. В одном спортзале есть много клиентов (один-ко-многим). В одном тренажерном зале также есть много тренеров и множество тренажерных залов. Каждая гимнастическая программа выполняется много раз в течение недели (класс гимнастики?). Каждый класс тренажерного зала имеет одно начальное время, одноразовое время и возглавляется одним (или, может быть, более) тренажером. В каждом классе гимнастики присутствуют ноль или более клиентов. Вы снова видите: думайте в классах, а не в таблицах. После того, как вы знаете классы и их отношения (HAS/IS, один-ко-многим или один к одному), вы можете иметь представление о классах и отношениях, которые вы знаете, какие таблицы вам нужны и какие первичные/внешние ключи –

Смежные вопросы