Задать вопрос
@vrotender

Как лучше разбить на сущности?

Работаю над пет-проектом, хочу сделать онлайн кинотеатр, типа Кинопоиска.
Как лучше разбить предметную область на сущности. Бывают фильмы, бывают многосерийные фильмы (они же сериалы), т.е. это должны быть отдельные сущности или условно "фильм", от которого связь 1:M к "серии", и считать что фильмы, у которых больше 1 серии - это сериалы, тогда как быть с сезонами?
  • Вопрос задан
  • 164 просмотра
Подписаться 1 Простой Комментировать
Пригласить эксперта
Ответы на вопрос 4
firedragon
@firedragon
Не джун-мидл-сеньор, а трус-балбес-бывалый.
Film
id (guid)
name
duration (int second)
release (datetime)
....

Serial
id (guid)
name
.....

SerialTofilm
id (guid)
filmid (guid)
season (guid)
....

Исходя из этого
Традиционно сериалы онлайн разбиты на несколько сезонов, каждый из которых состоит из 10 и более эпизодов. Конечно, лучше начинать смотреть сериалы онлайн с ...


Соответственно на фронте примерно такой код

{
  "id": "19",
  "name": "LEXX",
  "actors": [
    {
      "id": "1",
      "name": "hhhhhhhh"
    }
  ],
  "isSerial": true,
  "seasons": [
    {
      "id": "555555555",
      "name": "season 1",
      "sequence": 1,
      "films": [
        { "id": 19,"name": "lexx 1" }
      ]
    },
    {
      "id": "555555556",
      "name": "season 2",
      "sequence": 2
    }
  ]
}
Ответ написан
Комментировать
mayton2019
@mayton2019
Bigdata Engineer
1:M к "серии", и считать что фильмы, у которых больше 1 серии - это сериалы, тогда как быть с сезонами?

Есть много способов как представлять данные в БД. В схеме Фильм - Сериал - Сезон нет единой правильной модели
как лучше это хранить. Наверное все зависит от users stories тоесть от хотелок пользователя. Например хочет ли пользователь видеть что СРЕДИ сериала вдруг появляется пропуск в сериях или есть пилотная серия (которую надо выделить отдельно). Или например есть серия в котороой нет озвучки. Вот эти все вопросы надо спросить эксперта. В данном случае - тебя поскольку ты придумываешь себе предметную область.

Поэтому сразу совет - придумай ее как можно проще. Пускай это будут просто фильмы. 1 таблица с фильмами. Реализуй ее. Посмотри на нее. Я думаю что уже на этом этапе твой пет-проект может стать бесконечно сложным. Еще не доходя до сериалов.

Вот такая-вот беда с пет-проектами. Неудержимая фантазия хотелок - бесконечная сложность реализации.
Ответ написан
Комментировать
tsklab
@tsklab
Здесь отвечаю на вопросы.
Серия — тот же фильм, только у него есть S02E03 атрибут и "главный" фильм.
В сети много подобных проектов в исходниках со структурой базы данных — посмотреть как сделано.
Например:
CREATE TABLE [dbo].[Film](
	[ID] [int] IDENTITY(1,1) NOT NULL,
	[Heading] [int] NULL,
	[HeadingGroup]  AS (isnull([Heading],[ID])),
	[HeadingName] [varchar](25) NULL,
	[HeadingClose] [bit] NULL,
	[SeriesName] [varchar](15) NULL,
	[Series] [smallint] NULL,
	[SeriesDigit] [smallint] NULL,
	[Season] [smallint] NULL,
	[Episode] [smallint] NULL,
	[HeadingNumber]  AS (isnull(isnull([SeriesName]+' ','серия ')+CONVERT([varchar],[Series]),'')+isnull((('s'+format([Season],'d2'))+'e')+format([Episode],'d2'),'')),
	[PartName] [varchar](15) NULL,
	[Part] [smallint] NULL,
	[PartDisplay]  AS (isnull(((', '+isnull([PartName],'часть'))+' ')+CONVERT([varchar],[Part]),'')),
	[HeadingKey]  AS (((left(CONVERT([varchar],[Heading]),(0))+isnull('c'+format([Series],'d2'),''))+isnull((('s'+format([Season],'d2'))+'e')+format([Episode],'d2'),''))+isnull('p'+right('00'+CONVERT([varchar],[Part]),(2)),'')),
	[SeasonCount] [smallint] NULL,
	[Serias] [smallint] NULL,
	[Article] [varchar](20) NULL,
	[Name] [varchar](200) NULL,
	[NameTranslat] [varchar](200) NULL,
	[Year] [smallint] NULL,
	[Premiere] [smalldatetime] NULL,
	[PremiereDisplay]  AS (isnull(CONVERT([varchar],[Premiere],(104)),CONVERT([varchar],isnull([Year],(1985))))),
	[Country] [varchar](50) NULL,
	[Addition] [varchar](200) NULL,
	[TitleArticleLess]  AS ((([Name]+isnull((' ('+[NameTranslat])+')',''))+isnull((' ['+[Addition])+']',''))+isnull(((', '+isnull([PartName],'часть'))+' ')+CONVERT([varchar],[Part]),'')),
	[TitleBase]  AS ((((isnull([Article]+' ','')+[Name])+isnull((' ('+[NameTranslat])+')',''))+isnull((' ['+[Addition])+']',''))+isnull(((', '+isnull([PartName],'часть'))+' ')+CONVERT([varchar],[Part]),'')) PERSISTED,
	[TitleYear]  AS (((((isnull([Article]+' ','')+[Name])+isnull((' ('+[NameTranslat])+')',''))+isnull((' ['+[Addition])+']',''))+isnull(((', '+isnull([PartName],'часть'))+' ')+CONVERT([varchar],[Part]),''))+isnull(' · '+CONVERT([varchar],[Year],(104)),'')),
	[TitleCountry]  AS (((((isnull([Article]+' ','')+[Name])+isnull((' ('+[NameTranslat])+')',''))+isnull((' ['+[Addition])+']',''))+isnull(((', '+isnull([PartName],'часть'))+' ')+CONVERT([varchar],[Part]),''))+isnull(' · '+[Country],'')),
	[TitleYearCountry]  AS ((((((isnull([Article]+' ','')+[Name])+isnull((' ('+[NameTranslat])+')',''))+isnull((' ['+[Addition])+']',''))+isnull(((', '+isnull([PartName],'часть'))+' ')+CONVERT([varchar],[Part]),''))+isnull(' · '+CONVERT([varchar],[Year],(104)),''))+isnull(' · '+[Country],'')),
	[ShowTitleArticleLess]  AS (isnull(([Name]+isnull((' ('+[NameTranslat])+')',''))+isnull((' ['+[Addition])+']',''),'')),
	[ShowPart]  AS (isnull(((', '+isnull([PartName],'часть'))+' ')+CONVERT([varchar],[Part]),'')),
	[Cover] [image] NULL,
	[Note] [text] NULL,
	[NotWatch] [bit] NULL,
	[LastWatch] [datetime] NULL,
	[LastWatchDaysAgo]  AS (datediff(day,[LastWatch],getdate())),
	[DateWatch] [datetime] NULL,
	[WatchDisplay]  AS ((isnull('+ '+CONVERT([varchar],[DateWatch],(104)),'')+isnull(case when [DateWatch] IS NULL then CONVERT([varchar],[LastWatch],(104)) else (' ('+CONVERT([varchar],[LastWatch],(104)))+')' end,''))+case when NOT [NotWatch] IS NULL then ' x' else '' end),
	[PauseWatch] [datetime] NULL,
	[Range]  AS (((((isnull(CONVERT([varchar](4),[Year]),'1895')+format(isnull([Series],(0)),'d2'))+format(isnull([Season],(0)),'d2'))+format(isnull([Episode],(0)),'d2'))+format(isnull([Part],(0)),'d2'))+isnull(upper([Name]),'')),
	[SearchValue]  AS (replace(rtrim([Name]),' ','+')),
	[Icon]  AS (CONVERT([bit],isnull(datalength([Note]),(0)),(0))+CONVERT([bit],isnull(datalength([Cover]),(0)),(0))*(2)),
	[AttributeIcon] [bit] NULL,
	[Key]  AS ('F'+CONVERT([varchar],[ID])),
 CONSTRAINT [PK_Film] PRIMARY KEY CLUSTERED 
(
	[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

ALTER TABLE [dbo].[Film] ADD  CONSTRAINT [DF_Film_AttributeIcon]  DEFAULT ((0)) FOR [AttributeIcon]
GO

ALTER TABLE [dbo].[Film]  WITH CHECK ADD  CONSTRAINT [FK_Film_Film] FOREIGN KEY([Heading])
REFERENCES [dbo].[Film] ([ID])
GO

ALTER TABLE [dbo].[Film] CHECK CONSTRAINT [FK_Film_Film]
GO
Ответ написан
Комментировать
@jazzus
Film
id
name
film_type_id

FilmType (Полный метр, Короткий метр, Сериал)
id
name

Episode (серии)
id
name
film_id
season_id

Season
id
number
year
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы