Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Работа Новый топик    Ответить
Топик располагается на нескольких страницах: 1 2      [все]
 Стандартные требования на вакансию SQL junior dev  [new]
Troi51
Member

Откуда:
Сообщений: 10
Модератор: Вынесено из https://www.sql.ru/forum/1333789


zorrocool,

Здравствуйте.

Я не так давно начал плотно изучать SQL и сопутствующие ему технологии (в частности, остановился на MS SQL Server). Имеется большое желание перерасти из "что-то там умею" в полноценного джуниора с последующим трудоустройством и развитием. Но возникла проблема с определением набора навыков и направлением развития. Спрашивал на форуме, но особо пользы это не принесло, и из-за этого решил спрашивать точечно.
Поэтому хотел бы у Вас уточнить, как у полноценного работодателя:
1. У Вас в требованиях указаны "основные принципы проектирования реляционных баз данных (нормальные формы)". Какие НФ необходимо знать (и понимать, само собой), что бы соискатель удовлетворял предъявляемым требованиям?
2. Что Вы вкладываете в понятие "понимать принципы работы с индексами" ? Достаточно ли будет знать принцип работы индекса или нужны более глубокие познания?

Понимаю, что требования разнятся от вакансии к вакансии, но хотелось бы услышать именно Вашу точку зрения.

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

Сообщение было отредактировано: 29 мар 21, 12:58
23 мар 21, 19:10    [22299069]     Ответить | Цитировать Сообщить модератору
 Re: Стандартные требования на вакансию SQL junior dev  [new]
godsql
Member

Откуда:
Сообщений: 181
Troi51,

По моему личному мнению, все эти " (нормальные формы)". Какие НФ необходимо знать (и понимать, само собой), что бы соискатель удовлетворял предъявляемым требованиям?" представляют чисто академический интерес для показа образованности.
В реальности, в лучшем случае, вы столкнетесь с принципами "достаточной избыточности", а в худшем - "тихий ужас", где поклонник принципов нормализации повесится сразу, только взглянув на это изделие :)
23 мар 21, 20:28    [22299095]     Ответить | Цитировать Сообщить модератору
 Re: Стандартные требования на вакансию SQL junior dev  [new]
DaniilSeryi
Member

Откуда:
Сообщений: 1844
Troi51, выкиньте из требований zorrocool оптимизацию запросов, секционирование и опыт работы с системами контроля версий - вполне приличный джуниор на пол-пути к миддлу, а то и миддл получится.

Ну, и по мелочи надо будет знать:
что такое dml и ddl;
про разницу между типами varchar и char, а также varchar и nvarchar;
и что такое ntext, и где хранятся значения поля такого типа;
что такое статистика в SQL Server;
про разные виды индексов, включая кластерные, некластерные, фильтрованные индексы и не фильтрованные, с ключом из одного поля и из нескольких, с included-полями и без, что такое покрывающие индексы и что такое columnstore индексы, и т.д.;
про максимальную длину ключа индекса;
сколько может быть кластерных индексов на таблицу и почему;
и сколько может быть некластерных индексов на таблицу;
что такое scan и seek;
разницу между ограничениями primary key и unique не забывать;
вообще знать про constraint-ы всякие, включая default;
быть в курсе про вычисляемые столбцы, и чем обычные вычисляемые столбцы отличаются от постоянных (persisted);
быть в курсе про типы recovery model базы данных;
суметь ответить на вопрос о типах функций;
и суметь ответить на вопрос о том, как передать в функцию таблицу;
помнить про разницу между табличной переменной, временной таблицей и постоянной временной таблицей;
не путать delete, drop и truncate table;
знать, что на самом деле update - это delete с insert-ом;
быть в курсе про разные уровни выполнения триггеров, знать типы триггеров, и помнить про логон-триггеры;
также быть в курсе, когда именно имеет смысл создавать триггеры, а когда не стоит;
поработать с курсором хотя бы раз;
поработать с common table expression;
поработать с регрессиями с использованием common table expression;
ответить, чем отличается where от having;
ответить, в чём разница между count(*), count(ИмяПоля) и count(distinct ИмяПоля).
и т.д.

Про уровни изоляции транзакций и типы и уровни блокировок - это уже сильно позже.
Про секционирование (партиционирование) - тоже сильно позже.

Про высшее шаманство, как сделать, чтобы табличное представление ВСЕГДА возвращало отсортированный набор данных - это не спросят.

Сообщение было отредактировано: 23 мар 21, 20:37
23 мар 21, 20:35    [22299097]     Ответить | Цитировать Сообщить модератору
 Re: Стандартные требования на вакансию SQL junior dev  [new]
DaniilSeryi
Member

Откуда:
Сообщений: 1844
godsql
Troi51,

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


Джун должен их помнить, а миддл и выше - уметь применять автоматически.
23 мар 21, 20:40    [22299100]     Ответить | Цитировать Сообщить модератору
 Re: Стандартные требования на вакансию SQL junior dev  [new]
DaniilSeryi
Member

Откуда:
Сообщений: 1844
А... Про типы соединений забыл... Для джуниора - надо знать inner, cross и outer join (left, right, full), а также outer apply.

А вот hash, merge и loop join - это уже совсем другая вещь - её надо знать уже миддлу и выше.

Сообщение было отредактировано: 23 мар 21, 20:43
23 мар 21, 20:50    [22299103]     Ответить | Цитировать Сообщить модератору
 Re: Стандартные требования на вакансию SQL junior dev  [new]
Troi51
Member

Откуда:
Сообщений: 10
DaniilSeryi,

Огромное Вам человеческое спасибо за столь подробный и обстоятельный ответ! Я не ожидал даже, честно говоря. Буду изучать и постигать, благо в документации и примерах использования я недостатка на текущий момент не встречал.
23 мар 21, 22:14    [22299131]     Ответить | Цитировать Сообщить модератору
 Re: Стандартные требования на вакансию SQL junior dev  [new]
DaniilSeryi
Member

Откуда:
Сообщений: 1844
Troi51,

Завтра набросаю примеры задач, которые могут давать на собеседованиях.
23 мар 21, 23:04    [22299154]     Ответить | Цитировать Сообщить модератору
 Re: Стандартные требования на вакансию SQL junior dev  [new]
Troi51
Member

Откуда:
Сообщений: 10
DaniilSeryi,

Добрый день. Прошу прощения за беспокойство, но не могли бы всё таки набросать примеров? Вектор развития, обозначенный Вами до этого, очень помогает сейчас, к слову.
27 мар 21, 10:04    [22300687]     Ответить | Цитировать Сообщить модератору
 Re: Стандартные требования на вакансию SQL junior dev  [new]
DaniilSeryi
Member

Откуда:
Сообщений: 1844
Для разминки вот эти семь. Обратите внимание - в пунктах 1 и 2 Вы должны дать ответ, не выполняя код. Потом запустите код и проверьте. Если сможете объяснить, почему именно получился тот результат, что получился - ещё лучше.

1) Что вернет запрос при последовательном выполнении команд?

create table tab1
(
	id int not null,
	val int
);

select 'abc' from tab1
union
select 'abc' from tab1
union all
select 'abcdefg' from tab1;



2) Что вернут запросы?

create table tab1
(
	id int not null,
	val int
);
insert into tab1 (id, val) values (1, 1);
insert into tab1 (id, val) values (2, 2);
insert into tab1 (id, val) values (3, 3);
insert into tab1 (id, val) values (4, null);

select count(*), count(id), count(val), max(val) from tab1;
select * from tab1 where val in (select val from tab1);
select * from tab1 where val not in (select val from tab1);



3) Написать запрос, который выведет значения всех полей таблицы по условию:
Для каждого id_parent выбирать только первые 3 id, отсортированные по убыванию.
Если для id_parent не набирается 3х id, то такие случаи не выводить
table tab2
(
	id int not null,
	id_parent int
);



4) Написать запрос, который выводит список id, у которых кол-во значений val:
- равных 3 больше 10 штук
- или равных 4 больше 5 штук
table tab1
(
	id int not null,
	val int
);



5)
table tab_department --Справочник департаментов
(
	id_dep int not null,
	dep_name varchar(100) not null
);

table tab_empl --Справочник сотрудников
(
	id_emp int not null,
	fio varchar(100) not null,
	id_dep int, --ИД департамента
	id_emp_manager int, --ИД руководителя
	lvl int not null-- уровень
);

Написать запрос, который вернет список департаментов и кол-во работающих там тех сотрудников, у которых нет руководителя или его руководитель выше 10 уровня


6)
table tab1
(
	id int GENERATED BY DEFAULT AS IDENTITY not null,
	val int not null
);

table tab2
(
	id int not null,
	val_src int
);

table tab3
(
	id int not null,
	val_src int
);


В таблицу tab1 в поле val необходимо загрузить значения val_src из таблиц tab2 и tab3.
Написать скрипт, который вставит только те значения val_src, которых еще не было в таблице tab1


7)
table tab_empl --Справочник сотрудников
(
	id_emp int not null,
	fio varchar(100) not null,
	id_dep int, --ИД департамента
	id_emp_manager int, --ИД руководителя
	grade int not null-- уровень
);


Для всех сотрудников проставить уровень, как уровень его руководителя минус 1. Если у сотрудника нет руководителя, то оставить уровень неизменным

Сообщение было отредактировано: 27 мар 21, 20:05
27 мар 21, 20:05    [22300880]     Ответить | Цитировать Сообщить модератору
 Re: Стандартные требования на вакансию SQL junior dev  [new]
DaniilSeryi
Member

Откуда:
Сообщений: 1844
Из более сложного вот такое - но это уже для уверенного миддла, как мне кажется. Для одной из задач есть подсказка - там может помочь алгоритм "Острова" / Islands.
Также четвёртая задача из перечня требует генерации данных, которая может занять до нескольких часов. В случае с ней можете ограничиться ответом на вопрос про индексы.

+
SET NOCOUNT ON
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
GO
create database Exam_Open
go
use Exam_Open
go
--/*
IF OBJECT_ID('[TestDoc].[Accounts]') IS NOT NULL
  DROP TABLE [TestDoc].[Accounts]

IF OBJECT_ID('[TestDoc].[Contracts]') IS NOT NULL
  DROP TABLE [TestDoc].[Contracts]
--*/
--------------------------------------------------------------------------------------
-- Структура данных                                                                 --
--------------------------------------------------------------------------------------
IF SCHEMA_ID('TestDoc') IS NULL
  EXEC('
    CREATE SCHEMA [TestDoc]
  ')
GO

IF OBJECT_ID('[TestDoc].[Contracts]') IS NULL
  -- Договора
  CREATE TABLE [TestDoc].[Contracts]
  (
    [Id]        Int           NOT NULL  IDENTITY(1,1),
    [DocNo]     NVarChar(50)  NOT NULL,
    [DateFrom]  Date          NOT NULL, --  Дата, когда договор начал действовать
    [DateTo]    Date              NULL, --  Дата, когда договор прекращает действовать (последний день действия договора); NULL = бесконечность
    -- ... И еще какие-то поля
    PRIMARY KEY CLUSTERED([Id])
  )
GO

IF OBJECT_ID('[TestDoc].[Accounts]') IS NULL
  -- Счета
  CREATE TABLE [TestDoc].[Accounts]
  (
    [Id]            Int           NOT NULL  IDENTITY(1,1),
    [Contract_Id]   Int           NOT NULL, -- Договор, в рамках которого счет заключен
    [Number]        NVarChar(50)  NOT NULL, -- Номер счета
    [DateTimeFrom]  DateTime      NOT NULL, -- Момент времени (дата+время!), когда счет начал действовать
    [DateTimeTo]    DateTime          NULL, -- Момент времени (дата+время!), когда счет прекратил действовать
    -- ... И еще какие-то поля
    PRIMARY KEY CLUSTERED([Id]),
    FOREIGN KEY ([Contract_Id]) REFERENCES [TestDoc].[Contracts] ([Id])
  )
GO

/*
-----------------------------------------------------
Задача 1. 
-----------------------------------------------------
Напишите скрипт, который вернет список "ошибок" в учетной системе.
Под "ошибкой" подразумевается ситуация, когда счет действует (действовал), а договор, в рамках которого заключен счет, не действует (не действовал).
--*/

set nocount on
set ansi_nulls on
set quoted_identifier on
go

--/*
------------------------------------------------------------------
-- Создание структуры
------------------------------------------------------------------
if schema_id('Test') is null
  exec('create schema [Test]')
go

if object_id('[Test].[Contracts]') is null
  create table [Test].[Contracts]
  (
    [Id]          int   not null identity(1,1),
    [Type_Id]     int   not null,
    [Client_Id]   int   not null,
    [DateFrom]    date  not null,
    [DateTo]      date      null,
    primary key clustered ([Id])
  )
go

/*


-----------------------------------------------------
Задача 2. Версия: v08
-----------------------------------------------------
Напишите скрипт, который вернет список всех не пересекающихся и несмежных периодов
(т.е., между двумя периодами должен быть минимум один «пустой» день) между
@DateBegin и @DateEnd включительно, когда у клиента был хотя бы один активный договор типа @Type_Id.
Учесть, что у клиента может быть несколько действующих договоров.

Результат должен быть представлен в следующем виде:
-- Client_Id        -- Клиент
-- First_Date       -- Дата начала непрерывного периода действия договора(-ов) заданного типа
-- Last_Date        -- Дата окончания непрерывного периода действия договора(-ов) заданного типа

--*/
set nocount on
set ansi_nulls on
set quoted_identifier on
go

--/*
------------------------------------------------------------------
-- Создание структуры
------------------------------------------------------------------
if schema_id('TestCars') is null
  exec('create schema [TestCars]')
go

if object_id('[TestCars].[Points]') is null
  -- Точки
  create table [TestCars].[Points]
  (
    [Id]          int     not null identity(1,1),
    [Type_Id]     char(1) not null,               -- тип точки: D = Склад; S = Магазин
    primary key clustered ([Id]),
    check ([Type_Id] in ('D', 'S'))
  )
go

if object_id('[TestCars].[Cars]') is null
  -- Машины
  create table [TestCars].[Cars]
  (
    [Id]          int     not null identity(1,1),
    [Capacity]    int     not null,               -- Грузоподьемность
    primary key clustered ([Id])
  )
go

if object_id('[TestCars].[Routes]') is null
  -- Машины
  create table [TestCars].[Routes]
  (
    [Id]            int       not null identity(1,1),
    [Point_Id]      int       not null,
    [Car_Id]        int       not null,
    [Load]          int       not null,               -- Изменение загрузки авто при посещении данной точки. +N = в авто дозагрузили N кг; -N = из машины выгрузили N кг
                                                      -- При этом в магазине точка разгружается, а при посещении склада загружается/дозагружается
    [ArrivalTime]   datetime  not null,
    [DepartureTime] datetime  not null,
    primary key clustered ([Id]),
    foreign key ([Point_Id]) references [TestCars].[Points] ([Id]),
    foreign key ([Car_Id]) references [TestCars].[Cars] ([Id])
  )
go


/*
ВНИМАНИЕ! В начале скрипта-решения в комментариях укажите, пожалуйста, Ваши ФИО.

-----------------------------------------------------
Задача 3. Версия: v08
-----------------------------------------------------
В течение дня машина совершает несколько поездок. Каждая поездка начинается с загрузки машины на складе.
Далее машина посещает несколько магазинов, в каждом из которых частично разгружается.
Затем машина может прибыть на один из складов, дозагрузиться и начать следующий маршрут.
Каждый маршрут всегда проезжается в течение одного календарного дня (нет маршрутов с началом и концом в разных днях).
Машина движется всегда с одной и той же скоростью, скорости разных машин могут отличаться.
По одному и тому же маршруту может проехать несколько различных машин.

Надо 
1. найти топ-3 неэффективных маршрутов и топ-3 неэффективных машин по каждому из критериев:
1.1. Недозагруженность машины, т.е. отношение «загрузка машины/грузоподъемность» после выезда со склада в начале маршрута
1.2. Размер остатка в машине после посещения всех магазинов на маршруте
2. Найти самую быструю машину или доказать, что по представленным данным это невозможно сделать.


SET NOCOUNT ON
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
GO

--/*
IF OBJECT_ID('[TestMoney].[Operations]') IS NOT NULL
  DROP TABLE [TestMoney].[Operations]

IF OBJECT_ID('[TestMoney].[Currencies Rates]') IS NOT NULL
  DROP TABLE [TestMoney].[Currencies Rates]

IF OBJECT_ID('[TestMoney].[Currencies]') IS NOT NULL
  DROP TABLE [TestMoney].[Currencies]

IF OBJECT_ID('[TestMoney].[Clients]') IS NOT NULL
  DROP TABLE [TestMoney].[Clients]
--*/
--------------------------------------------------------------------------------------
-- Структура данных                                                                 --
-- (*) исключительно для тестирования, не претендует на реальность и адекватность   --
--------------------------------------------------------------------------------------
IF SCHEMA_ID('TestMoney') IS NULL
  EXEC('
    CREATE SCHEMA [TestMoney]
  ')
GO

IF OBJECT_ID('[TestMoney].[Clients]') IS NULL
  CREATE TABLE [TestMoney].[Clients]
  (
    [Id]        Int                                   NOT NULL  IDENTITY(1,1),
    [Name]      NVarChar(128)                         NOT NULL,
    -- ... И еще какие-то поля
    PRIMARY KEY CLUSTERED([Id])
  )
GO
IF OBJECT_ID('[TestMoney].[Currencies]') IS NULL
  CREATE TABLE [TestMoney].[Currencies]
  (
    [Id]        Int                                   NOT NULL,
    [CodeLat3]  Char(3) COLLATE Cyrillic_General_BIN  NOT NULL,
    [Name]      NVarChar(128)                         NOT NULL,
    PRIMARY KEY CLUSTERED([Id])
  )
GO
IF OBJECT_ID('[TestMoney].[Currencies Rates]') IS NULL
  CREATE TABLE [TestMoney].[Currencies Rates]
  (
    [Currency_Id]       Int           NOT NULL, -- Валюту, курс которой указан
    [BaseCurrency_Id]   Int           NOT NULL, -- Базовая валюта; для пары USD/RUB в поле ВaseCurrency_Id будет ссылка на RUB; в поле Currency_Id - ссылка на USD; в поле Rate = курс = 60; т.е. 60 RUB = 1 USD
    [Date]              Date          NOT NULL, -- Дата курса
    [Rate]              Numeric(32,8) NOT NULL, -- Собственно курс 
    [Volume]            Numeric(18,8) NOT NULL, -- За количество; Например, за 10 000 Белорусских рублей дают 39.4419 Рублей; Rate = 39.4419; Volume = 10 000;
    PRIMARY KEY CLUSTERED([Currency_Id], [BaseCurrency_Id], [Date]),
    FOREIGN KEY ([Currency_Id]) REFERENCES [TestMoney].[Currencies] ([Id]),
    FOREIGN KEY ([BaseCurrency_Id]) REFERENCES [TestMoney].[Currencies] ([Id])
  )
-- Чтобы получить сумму Sb в @BaseCurrency_Id, если у Вас есть сумма Sc в валюте Currency_Id,
-- то надо найти на интересующую дату такую ближайшую по дате запись (курс есть не на каждый день),
-- где [BaseCurrency_Id] = @BaseCurrency_Id и [Currency_Id] = @Currency_Id и [Date] <= @Date,
-- умножить на Rate и разделить на Volume
-- т.е. Sb = Sc * Rate / Volume на требуемую дату
GO

IF OBJECT_ID('[TestMoney].[Operations]') IS NULL
  CREATE TABLE [TestMoney].[Operations]
  (
    [Id]                Int           NOT NULL IDENTITY(1,1),
    [Date]              Date          NOT NULL,               -- Дата операции
    [Client_Id]         Int           NOT NULL,               -- Клиент, по которому меняется баланс
    [Value]             Numeric(32,8) NOT NULL,               -- Сумма, на которую меняется баланс
    [Currency_Id]       Int           NOT NULL,               -- Валюта операции
    [DocNo]             NVarChar(32)      NULL,
    -- ... И еще какие-то поля
    PRIMARY KEY CLUSTERED([Id]),
    FOREIGN KEY ([Currency_Id]) REFERENCES [TestMoney].[Currencies] ([Id]),
    FOREIGN KEY ([Client_Id]) REFERENCES [TestMoney].[Clients] ([Id])
  )
GO

----------------------------------------------------
-- Генерация данных
-----------------------------------------------------
/*
TRUNCATE TABLE [TestMoney].[Operations]
TRUNCATE TABLE [TestMoney].[Currencies Rates]

DELETE FROM [TestMoney].[Currencies]
DELETE FROM [TestMoney].[Clients]
--*/
GO
--/*
INSERT INTO [TestMoney].[Clients] ([Name])
SELECT
  [Name]    = CAST(O1.[object_id] AS NVarChar(128)) + ' - ' + CAST(O2.[object_id] AS NVarChar(128))
FROM
(
  SELECT TOP (100)
    O.[object_id]
  FROM sys.all_objects O
) O1
CROSS APPLY
(
  SELECT TOP (20)
    O.[object_id]
  FROM sys.all_objects O
) O2
GO

INSERT INTO [TestMoney].[Currencies]
VALUES
  (1, 'RUB', 'Рубль'),
  (2, 'USD', 'Доллар США'),
  (3, 'EUR', 'Евро'),
  (4, 'JPY', 'Йена'),
  (5, 'BYR', 'Белорусский рубль')
GO

DECLARE @DateStart Date = '20130101'
INSERT INTO [TestMoney].[Currencies Rates]
SELECT
  [Currency_Id]     = C.[Id],
  [BaseCurrency_Id] = 1,
  [Date]            = DATEADD(Day, I.[RowNumber], @DateStart),
  [Rate]            = CASE C.[CodeLat3]
                        WHEN 'USD' THEN 40 - 10 + RAND( CAST(CAST(RIGHT(NewId(), 4) AS Binary(4)) AS Int) ) * 20
                        WHEN 'EUR' THEN 50 - 10 + RAND( CAST(CAST(RIGHT(NewId(), 4) AS Binary(4)) AS Int) ) * 20
                        WHEN 'JPY' THEN 40 - 10 + RAND( CAST(CAST(RIGHT(NewId(), 4) AS Binary(4)) AS Int) ) * 20
                        WHEN 'BYR' THEN 35 - 7 + RAND( CAST(CAST(RIGHT(NewId(), 4) AS Binary(4)) AS Int) ) * 15
                      END,
  [Volume]          = CASE
                        WHEN C.[CodeLat3] = 'BYR' THEN 10000
                        WHEN C.[CodeLat3] = 'JPY' THEN 100
                        ELSE 1
                      END
FROM [TestMoney].[Currencies] C
CROSS APPLY
(
  SELECT TOP (365*3)
    [RowNumber]     = ROW_NUMBER() OVER (ORDER BY O1.[object_id], O2.[object_id])
  FROM
  (
    SELECT TOP (100)
      O.[object_id]
    FROM sys.all_objects O
  ) O1
  CROSS APPLY
  (
    SELECT TOP (50)
      O.[object_id]
    FROM sys.all_objects O
  ) O2
) I
WHERE C.[Id] > 1 -- кроме рубля
  AND I.[RowNumber] % 10 > 2 -- чтобы были пробелы в курсах
GO

-- За 3 года 2013, 2014, 2015
-- Учтите, что время заполнения может дойти до 1 часа!
DECLARE
  @DateStart  Date        = '20130101',
  @N          Int         = 12 * 3,
  @DebugTime  DateTime    = GETDATE()

WHILE @N > 0 BEGIN

  INSERT INTO [TestMoney].[Operations] ([Date], [Client_Id], [Value], [Currency_Id], [DocNo])
  SELECT
    [Date]        = DATEADD(Day, I.[RowNumber], @DateStart),
    [Client_Id]   = C.[Id],
    [Value]       = RAND( CAST(CAST(RIGHT(NewId(), 4) AS Binary(4)) AS Int) ) * 1000 - 500,
    [Currency_Id] = CR.[Id],
    [DocNo]       = CAST(C.[Id] AS NVarChar(20)) + N'/' + CAST(CR.[Id] AS NVarChar(20)) + N'/' + CAST(I.[RowNumber] AS NVarChar(20)) + N'-' + CAST(I2.[RowIndex] AS NVarChar(20))
  FROM [TestMoney].[Clients]          C
  CROSS JOIN [TestMoney].[Currencies] CR
  CROSS APPLY
  (
    SELECT TOP (30)
      [RowNumber]     = ROW_NUMBER() OVER (ORDER BY O.[object_id])
    FROM sys.all_objects O
  ) I
  CROSS APPLY
  (
    SELECT TOP (20)
      [RowIndex]      = ROW_NUMBER() OVER (ORDER BY O.[object_id])
    FROM sys.all_objects O
  ) I2

  SET @DateStart = DATEADD(Month, 1, @DateStart)
  SET @N -= 1

END

SELECT [RUN_TIME] = CONVERT(VarChar(20), GETDATE() - @DebugTime, 114)
--*/
GO

/*

-----------------------------------------------------
Задача 4. Версия: v07
-----------------------------------------------------
Напишите скрипт, который вернет обороты по клиентам в следующем виде:
-- Client_Id        -- Клиент
-- Currency_Id      -- Валюта
-- BaseBalance      -- Изменение баланса клиента в базовой валюте = сумма всех операций, у которых Date >= @DateFrom и Date < @DateTo
Порядок вывода данных:
--ORDER BY
--  Client_Id, Currency_Id

При этом входящие параметры:
  @BaseCurrency_Id        - идентификатор базовой валюты, к которой надо привести сумму Balance;
  @DateFrom, @DateTo      - период за который надо расчитать баланс клиента

При написании скрипта предположите, что в таблице [TestMoney].[Currencies Rates] есть курсы для [BaseCurrency_Id] = @BaseCurrency_Id
(т.е. не надо усложнять задачу до кросс-курсов)

Условие: в таблице Operations очень много данных. @DateFrom и @DateTo, как правило, небольшой период (не более 1 недели при общей истории данных в Operations не менее 3-х лет)
Предложите хороший индекс(ы) для данного запроса(ов).

Прокомментируйте/обоснуйте Ваш выбор. Какие были варианты. Почему "да"/"нет"?
--*/
GO

-----------------------------------------------------
-- Пример тестовых параметров:
-----------------------------------------------------

DECLARE
  @DateFrom         Date    = '20150101'
DECLARE
  @DateTo           Date    = DATEADD(Day, 7, @DateFrom),
  @BaseCurrency_Id  Int     = 1


Сообщение было отредактировано: 29 мар 21, 12:59
27 мар 21, 20:26    [22300890]     Ответить | Цитировать Сообщить модератору
 Re: Стандартные требования на вакансию SQL junior dev  [new]
DaniilSeryi
Member

Откуда:
Сообщений: 1844
Также на собеседованиях любят спрашивать задачку про удаление дублирующихся строк из таблицы, в которой нет поля ID. Здесь надо использовать оконную функцию Row_number().
Пример таблицы, для которой надо написать запрос на удаление дублей:

CREATE TABLE TEST.C
(
  B VARCHAR(255)
)

INSERT INTO TEST.C(B) VALUES ('AAA');
INSERT INTO TEST.C(B) VALUES ('ABA');
INSERT INTO TEST.C(B) VALUES ('AAB');
INSERT INTO TEST.C(B) VALUES ('ABB');
INSERT INTO TEST.C(B) VALUES ('BBA');
INSERT INTO TEST.C(B) VALUES ('AAA');
INSERT INTO TEST.C(B) VALUES ('AAA');
INSERT INTO TEST.C(B) VALUES ('ABB');
INSERT INTO TEST.C(B) VALUES ('BBA');



Другой вопрос, который многие любят:
--Создайте таблицу
create schema test;
go
CREATE TABLE TEST.A
(
B int
)
;
INSERT INTO TEST.A(B) VALUES (1);
INSERT INTO TEST.A(B) VALUES (NULL);
INSERT INTO TEST.A(B) VALUES (2);
INSERT INTO TEST.A(B) VALUES (3);

--Ответьте, какие результаты вернут запросы к таблице, приведенные ниже?

SELECT * FROM TEST.A;

SELECT * FROM TEST.A WHERE 1 = 1;

SELECT * FROM TEST.A WHERE NULL = '';

SELECT * FROM TEST.A WHERE B != 1;

SELECT * FROM TEST.A WHERE B = B;

SELECT * FROM TEST.A WHERE B NOT IN (1,NULL);

SELECT * FROM TEST.A WHERE B IN (1,NULL);


И ещё один любимый многими вопрос. Могут попросить написать результаты запросов к таблицам, могут попросить подсчитать и сказать число строк, которые вернут запросы:
create schema test;
go
CREATE TABLE TEST.E
(
B int
)
;
INSERT INTO TEST.E(B) VALUES (1);
INSERT INTO TEST.E(B) VALUES (1);
INSERT INTO TEST.E(B) VALUES (NULL);
INSERT INTO TEST.E(B) VALUES (3);
INSERT INTO TEST.E(B) VALUES (4);

CREATE TABLE TEST.F
(
C int
)
;
INSERT INTO TEST.F(C) VALUES (1);
INSERT INTO TEST.F(C) VALUES (NULL);
INSERT INTO TEST.F(C) VALUES (NULL);
INSERT INTO TEST.F(C) VALUES (2);
INSERT INTO TEST.F(C) VALUES (2);
INSERT INTO TEST.F(C) VALUES (4);
INSERT INTO TEST.F(C) VALUES (5);

SELECT * 
FROM TEST.E
INNER JOIN TEST.F ON B=C;

SELECT * 
FROM TEST.E
LEFT JOIN TEST.F ON B=C;

SELECT * 
FROM TEST.E
RIGHT JOIN TEST.F ON B=C;

SELECT * 
FROM TEST.E
FULL JOIN TEST.F ON B=C;

SELECT * 
FROM TEST.E
CROSS JOIN TEST.F;


Сообщение было отредактировано: 27 мар 21, 20:49
27 мар 21, 20:55    [22300903]     Ответить | Цитировать Сообщить модератору
 Re: Стандартные требования на вакансию SQL junior dev  [new]
DaniilSeryi
Member

Откуда:
Сообщений: 1844
Ну и ещё одно упражнение. Посмотрите код. Скажите, какие значения вернут запросы select. Почему?

create table dbo.a(id int)
go
create table dbo.a1(id int)
go
create table #b(id int)
go
create table #b1(id int)
go
declare @c table (id int)

begin tran
	insert into dbo.a(id) 
	values(1)

	insert into #b(id) 
	values(2)

	insert into @c(id) 
	values(3)
rollback tran;

select * from dbo.a
select * from #b
select * from @c

declare @c1 table (id int)

begin tran 
	insert into dbo.a1(id)
	values(1)

	insert into #b1(id) 
	values(2)

	insert into @c1(id) 
	values(3)
commit tran;


select * from dbo.a1
select * from #b1
select * from @c1
27 мар 21, 23:13    [22300940]     Ответить | Цитировать Сообщить модератору
 Re: Стандартные требования на вакансию SQL junior dev  [new]
monsenior
Member

Откуда: Москва
Сообщений: 893
DaniilSeryi
Также на собеседованиях любят спрашивать задачку про удаление дублирующихся строк из таблицы, в которой нет поля ID. Здесь надо использовать оконную функцию Row_number().


А на совсем правильных собесах спросят почему за использование Row_number() для поиска дублей бьют по рукам))
28 мар 21, 13:18    [22301047]     Ответить | Цитировать Сообщить модератору
 Re: Стандартные требования на вакансию SQL junior dev  [new]
DaniilSeryi
Member

Откуда:
Сообщений: 1844
monsenior
DaniilSeryi
Также на собеседованиях любят спрашивать задачку про удаление дублирующихся строк из таблицы, в которой нет поля ID. Здесь надо использовать оконную функцию Row_number().


А на совсем правильных собесах спросят почему за использование Row_number() для поиска дублей бьют по рукам))


Хм... И почему?
И какие тогда есть варианты решения задачи? помимо select distinct - delte - insert и с Row_number ?

Модератор: Тема перенесена из форума "Вакансии".


Сообщение было отредактировано: 29 мар 21, 12:53
28 мар 21, 13:46    [22301055]     Ответить | Цитировать Сообщить модератору
 Re: Стандартные требования на вакансию SQL junior dev  [new]
DaniilSeryi
Member

Откуда:
Сообщений: 1844
На самом деле, задача на удаление дублей заточена на знание и умение работать с оконными функциями.
Идёт часто в связке с вопросом, а какие оконные функции Вы знаете?

Сообщение было отредактировано: 28 мар 21, 13:58
28 мар 21, 13:57    [22301061]     Ответить | Цитировать Сообщить модератору
 Re: Стандартные требования на вакансию SQL junior dev  [new]
godsql
Member

Откуда:
Сообщений: 181
DaniilSeryi
На самом деле, задача на удаление дублей заточена на знание и умение работать с оконными функциями.
Идёт часто в связке с вопросом, а какие оконные функции Вы знаете?


на самом деле, если есть уникальный ключ/поле, то в дополнительной нумерации необходимости нет.
На куче - да, без row_number не обойдешься
28 мар 21, 15:33    [22301094]     Ответить | Цитировать Сообщить модератору
 Re: Стандартные требования на вакансию SQL junior dev  [new]
DaniilSeryi
Member

Откуда:
Сообщений: 1844
godsql
DaniilSeryi
На самом деле, задача на удаление дублей заточена на знание и умение работать с оконными функциями.
Идёт часто в связке с вопросом, а какие оконные функции Вы знаете?


на самом деле, если есть уникальный ключ/поле, то в дополнительной нумерации необходимости нет.
На куче - да, без row_number не обойдешься


Я же в описании задачи указал, что поля ID нету. :-)
28 мар 21, 23:15    [22301212]     Ответить | Цитировать Сообщить модератору
 Re: Стандартные требования на вакансию SQL junior dev  [new]
Dmitry_PV
Member

Откуда:
Сообщений: 70
DaniilSeryi, хорошие примеры, благодарю.
29 мар 21, 10:42    [22301300]     Ответить | Цитировать Сообщить модератору
 Re: Стандартные требования на вакансию SQL junior dev  [new]
yob
Member

Откуда:
Сообщений: 39
Troi51,
T-sql query
T-sql programming
r-sql perfomance tuning
Msdn
На начало хватит
29 мар 21, 15:03    [22301465]     Ответить | Цитировать Сообщить модератору
 Re: Стандартные требования на вакансию SQL junior dev  [new]
yob
Member

Откуда:
Сообщений: 39
yob
Troi51,
T-sql query
T-sql programming
r-sql perfomance tuning
Msdn
На начало хватит

ну еще сборник рецептов завхвати, о райли который
29 мар 21, 15:06    [22301467]     Ответить | Цитировать Сообщить модератору
 Re: Стандартные требования на вакансию SQL junior dev  [new]
Ivan Durak
Member

Откуда: Minsk!!!
Сообщений: 3669
godsql
DaniilSeryi
На самом деле, задача на удаление дублей заточена на знание и умение работать с оконными функциями.
Идёт часто в связке с вопросом, а какие оконные функции Вы знаете?


на самом деле, если есть уникальный ключ/поле, то в дополнительной нумерации необходимости нет.
На куче - да, без row_number не обойдешься

ну на нормальных базах эффективнее юзать rowid и ему подобные.
29 мар 21, 15:23    [22301477]     Ответить | Цитировать Сообщить модератору
 Re: Стандартные требования на вакансию SQL junior dev  [new]
Ivan Durak
Member

Откуда: Minsk!!!
Сообщений: 3669
но вообще все что касается понимания планов выполнения запросов я от джуниоров не требовал никогда.
Так что даю 95% что оно и не понадобится.
Ну и DBA знания - туда же, не требуются, я никогда не спрашивал,
По моему опыту отсобеседовав порядка 300 кандидатов в джуниоры sql уже хорошо если он может писать запросы с группировкой и having, умеет лефт джоином и иннером пользоваться ну и может модельку в 3нф на 3 таблички нарисовать и m:m свзязь.
Уже энаф, так сказать
29 мар 21, 15:30    [22301486]     Ответить | Цитировать Сообщить модератору
 Re: Стандартные требования на вакансию SQL junior dev  [new]
yob
Member

Откуда:
Сообщений: 39
Ivan Durak
но вообще все что касается понимания планов выполнения запросов я от джуниоров не требовал никогда.
Так что даю 95% что оно и не понадобится.
Ну и DBA знания - туда же, не требуются, я никогда не спрашивал,
По моему опыту отсобеседовав порядка 300 кандидатов в джуниоры sql уже хорошо если он может писать запросы с группировкой и having, умеет лефт джоином и иннером пользоваться ну и может модельку в 3нф на 3 таблички нарисовать и m:m свзязь.
Уже энаф, так сказать

Пахнет быстрым рефакторингом кода
29 мар 21, 15:41    [22301499]     Ответить | Цитировать Сообщить модератору
 Re: Стандартные требования на вакансию SQL junior dev  [new]
yob
Member

Откуда:
Сообщений: 39
yob
Ivan Durak
но вообще все что касается понимания планов выполнения запросов я от джуниоров не требовал никогда.
Так что даю 95% что оно и не понадобится.
Ну и DBA знания - туда же, не требуются, я никогда не спрашивал,
По моему опыту отсобеседовав порядка 300 кандидатов в джуниоры sql уже хорошо если он может писать запросы с группировкой и having, умеет лефт джоином и иннером пользоваться ну и может модельку в 3нф на 3 таблички нарисовать и m:m свзязь.
Уже энаф, так сказать

Пахнет быстрым рефакторингом кода

хотя хз, смотря какая предметная область, и что требуется в итоге, удтверждать не буду
29 мар 21, 15:48    [22301505]     Ответить | Цитировать Сообщить модератору
 Re: Стандартные требования на вакансию SQL junior dev  [new]
DaniilSeryi
Member

Откуда:
Сообщений: 1844
Не могу удержаться от того, чтобы не выложить.

Нашёл у себя кусочек теории со своими комментариями
Теория, которая нужна… …да никому она на практике не нужна. Честно говоря, у меня это на собеседованиях спросили только один раз. У Вас это спрашивают на собеседовании? Бегите оттуда.

Атрибут — свойство некоторой сущности. Нормальные люди называют это полем или столбцом таблицы.

Домен атрибута — множество допустимых значений, которые может принимать атрибут (значения, которые можно вводить в столбец таблицы).

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

Отношение — конечное множество кортежей (таблица).

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

Проекция — отношение, полученное из заданного путём удаления и (или) перестановки некоторых атрибутов.

Функциональная зависимость между атрибутами (множествами атрибутов) X и Y означает, что для любого допустимого набора кортежей в данном отношении: если два кортежа совпадают по значению X, то они совпадают по значению Y. Например, если значение атрибута «Название компании» — Canonical Ltd, то значением атрибута «Штаб-квартира» в таком кортеже всегда будет Millbank Tower, London, United Kingdom. Обозначение: {X} -> {Y}.

Аномалией называется такая ситуация в таблице БД, которая приводит к противоречию в БД либо существенно усложняет обработку БД. Причиной является излишнее дублирование данных в таблице, которое вызывается наличием функциональных зависимостей от не ключевых атрибутов.

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

Аномалии-удаления — при удалении какого либо кортежа из таблицы может пропасть информация, которая не связана на прямую с удаляемой записью.

Аномалии-добавления возникают, когда информацию в таблицу нельзя поместить, пока она не полная, либо вставка записи требует дополнительного просмотра таблицы.


И чуть больше приближенная к практике теория:
Нормальная форма — требование, предъявляемое к структуре таблиц в теории реляционных баз данных для устранения из базы избыточных функциональных зависимостей между атрибутами (полями таблиц).

Метод нормальных форм (НФ) состоит в сборе информации о объектах решения задачи в рамках одного отношения и последующей декомпозиции этого отношения на несколько взаимосвязанных отношений на основе процедур нормализации отношений.

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

На самом деле разработчику нормальные формы нужны только для того, чтобы понять и запомнить два простых правила: 1) одна ячейка таблицы – одно значение; 2) для каждого отдельного понятия (сущности) предметной области должна быть выделена своя собственная таблица.
Когда Вы спроектируете под контролем наставника свою первую БД, получите по шее за то, что предлагаете хранить в ячейке таблицы несколько значений и за то, что у Вас нет нужных таблиц-справочников, и Вы дублируете данные о сущностях текстом по всей таблице, тогда Вы намертво усвоите принципы, которые скрываются за формулировками нормальных форм. После этого формулировки нормальных форм Вам будут нужны только на собеседованиях, и то – степень адекватности тех, кто задаёт такие вопросы, вызывает сомнения.
29 мар 21, 21:24    [22301695]     Ответить | Цитировать Сообщить модератору
 Re: Стандартные требования на вакансию SQL junior dev  [new]
DaniilSeryi
Member

Откуда:
Сообщений: 1844
Какие бывают отношения между таблицами в РСУБД? Приведите возможный пример таких отношений.
Всего существует три вида связей между таблицами баз данных:
• связь один к одному;
• связь один ко многим;
• связь многие ко многим.
Примером связи один к одному является супружеская пара – одному мужу соответствует только одна жена, и одной жене соответствует только один муж.
Связь один ко многим – это султан и его гарем. У султана может быть много жён, но у каждой из них только один муж.
Связь многие ко многим – шведская семья. Первое: одну девочку могут любить несколько мальчиков. Второе: одного мальчика может любить несколько девочек. Здесь мы наблюдаем типичную ситуацию, когда связь между таблицами многие ко многим. Такая связь (связь многие ко многим) реализуется путем добавления третьей таблицы.

Источник: https://zametkinapolyah.ru/zametki-o-mysql/chast-3-2-vidy-svyazej-mezhdu-tablicami-v-baze-dannyx-svyazi-v-relyacionnyx-bazax-dannyx-otnosheniya-kortezhi-atributy.html#i-2
29 мар 21, 21:30    [22301698]     Ответить | Цитировать Сообщить модератору
 Re: Стандартные требования на вакансию SQL junior dev  [new]
Vyatich
Member

Откуда:
Сообщений: 3788
DaniilSeryi

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

Не рассмотрен случай когда одного мальчика могут любить несколько мальчиков и наоборот.
29 мар 21, 22:19    [22301717]     Ответить | Цитировать Сообщить модератору
 Re: Стандартные требования на вакансию SQL junior dev  [new]
yob
Member

Откуда:
Сообщений: 39
DaniilSeryi
Не могу удержаться от того, чтобы не выложить.

Нашёл у себя кусочек теории со своими комментариями
Теория, которая нужна… …да никому она на практике не нужна. Честно говоря, у меня это на собеседованиях спросили только один раз. У Вас это спрашивают на собеседовании? Бегите оттуда.

Атрибут — свойство некоторой сущности. Нормальные люди называют это полем или столбцом таблицы.

Домен атрибута — множество допустимых значений, которые может принимать атрибут (значения, которые можно вводить в столбец таблицы).

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

Отношение — конечное множество кортежей (таблица).

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

Проекция — отношение, полученное из заданного путём удаления и (или) перестановки некоторых атрибутов.

Функциональная зависимость между атрибутами (множествами атрибутов) X и Y означает, что для любого допустимого набора кортежей в данном отношении: если два кортежа совпадают по значению X, то они совпадают по значению Y. Например, если значение атрибута «Название компании» — Canonical Ltd, то значением атрибута «Штаб-квартира» в таком кортеже всегда будет Millbank Tower, London, United Kingdom. Обозначение: {X} -> {Y}.

Аномалией называется такая ситуация в таблице БД, которая приводит к противоречию в БД либо существенно усложняет обработку БД. Причиной является излишнее дублирование данных в таблице, которое вызывается наличием функциональных зависимостей от не ключевых атрибутов.

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

Аномалии-удаления — при удалении какого либо кортежа из таблицы может пропасть информация, которая не связана на прямую с удаляемой записью.

Аномалии-добавления возникают, когда информацию в таблицу нельзя поместить, пока она не полная, либо вставка записи требует дополнительного просмотра таблицы.


И чуть больше приближенная к практике теория:
Нормальная форма — требование, предъявляемое к структуре таблиц в теории реляционных баз данных для устранения из базы избыточных функциональных зависимостей между атрибутами (полями таблиц).

Метод нормальных форм (НФ) состоит в сборе информации о объектах решения задачи в рамках одного отношения и последующей декомпозиции этого отношения на несколько взаимосвязанных отношений на основе процедур нормализации отношений.

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

На самом деле разработчику нормальные формы нужны только для того, чтобы понять и запомнить два простых правила: 1) одна ячейка таблицы – одно значение; 2) для каждого отдельного понятия (сущности) предметной области должна быть выделена своя собственная таблица.
Когда Вы спроектируете под контролем наставника свою первую БД, получите по шее за то, что предлагаете хранить в ячейке таблицы несколько значений и за то, что у Вас нет нужных таблиц-справочников, и Вы дублируете данные о сущностях текстом по всей таблице, тогда Вы намертво усвоите принципы, которые скрываются за формулировками нормальных форм. После этого формулировки нормальных форм Вам будут нужны только на собеседованиях, и то – степень адекватности тех, кто задаёт такие вопросы, вызывает сомнения.

+1
В случае SQL теория должна быть подкреплена огромным количеством практики,
Как, в принципе, и в любом ЯП
30 мар 21, 01:05    [22301776]     Ответить | Цитировать Сообщить модератору
 Re: Стандартные требования на вакансию SQL junior dev  [new]
yob
Member

Откуда:
Сообщений: 39
yob
DaniilSeryi
Не могу удержаться от того, чтобы не выложить.

Нашёл у себя кусочек теории со своими комментариями
Теория, которая нужна… …да никому она на практике не нужна. Честно говоря, у меня это на собеседованиях спросили только один раз. У Вас это спрашивают на собеседовании? Бегите оттуда.

Атрибут — свойство некоторой сущности. Нормальные люди называют это полем или столбцом таблицы.

Домен атрибута — множество допустимых значений, которые может принимать атрибут (значения, которые можно вводить в столбец таблицы).

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

Отношение — конечное множество кортежей (таблица).

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

Проекция — отношение, полученное из заданного путём удаления и (или) перестановки некоторых атрибутов.

Функциональная зависимость между атрибутами (множествами атрибутов) X и Y означает, что для любого допустимого набора кортежей в данном отношении: если два кортежа совпадают по значению X, то они совпадают по значению Y. Например, если значение атрибута «Название компании» — Canonical Ltd, то значением атрибута «Штаб-квартира» в таком кортеже всегда будет Millbank Tower, London, United Kingdom. Обозначение: {X} -> {Y}.

Аномалией называется такая ситуация в таблице БД, которая приводит к противоречию в БД либо существенно усложняет обработку БД. Причиной является излишнее дублирование данных в таблице, которое вызывается наличием функциональных зависимостей от не ключевых атрибутов.

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

Аномалии-удаления — при удалении какого либо кортежа из таблицы может пропасть информация, которая не связана на прямую с удаляемой записью.

Аномалии-добавления возникают, когда информацию в таблицу нельзя поместить, пока она не полная, либо вставка записи требует дополнительного просмотра таблицы.


И чуть больше приближенная к практике теория:
Нормальная форма — требование, предъявляемое к структуре таблиц в теории реляционных баз данных для устранения из базы избыточных функциональных зависимостей между атрибутами (полями таблиц).

Метод нормальных форм (НФ) состоит в сборе информации о объектах решения задачи в рамках одного отношения и последующей декомпозиции этого отношения на несколько взаимосвязанных отношений на основе процедур нормализации отношений.

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

На самом деле разработчику нормальные формы нужны только для того, чтобы понять и запомнить два простых правила: 1) одна ячейка таблицы – одно значение; 2) для каждого отдельного понятия (сущности) предметной области должна быть выделена своя собственная таблица.
Когда Вы спроектируете под контролем наставника свою первую БД, получите по шее за то, что предлагаете хранить в ячейке таблицы несколько значений и за то, что у Вас нет нужных таблиц-справочников, и Вы дублируете данные о сущностях текстом по всей таблице, тогда Вы намертво усвоите принципы, которые скрываются за формулировками нормальных форм. После этого формулировки нормальных форм Вам будут нужны только на собеседованиях, и то – степень адекватности тех, кто задаёт такие вопросы, вызывает сомнения.

+1
В случае SQL теория должна быть подкреплена огромным количеством практики,
Как, в принципе, и в любом ЯП


В плане нормализации - хорошей практикой опираться на общеизвестные и общепринятые модели данных под конкретный вид бизнеса и предметную область. Т.к. условно, если вы напишите тз, заложив модель, то менять целая история, а если бизнес горячий - источники цепляются каждый день, внедряются новые расчеты, в итоге может получиться свалка и переделывать придется с нуля.
30 мар 21, 02:06    [22301782]     Ответить | Цитировать Сообщить модератору
 Re: Стандартные требования на вакансию SQL junior dev  [new]
Troi51
Member

Откуда:
Сообщений: 10
Господа, большое спасибо, что нашли время и возможность ответить и помочь советом. Приятно осознавать, что мир не без добрых людей. Крепко жму Вам руку.
30 мар 21, 02:14    [22301784]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: 1 2      [все]
Все форумы / Работа Ответить