Как лучше хранить GUID в базе (тип данных)?
GUID как PK, база Postgresql, для Oracle тоже интересно. В связке с EF.
Что скажете?
MS в своих примерах любит строки. Но что то многим это не нравится.
Как дефолтно хранится, так и храню
А какой именно тип в базе? База ПГ?
А как начну семь знаков за работу получать, так тоже думать об этом начну
Что то мне кажется тогда уже будет поздно
Вообще то никогда не имел связи между зарплатой и типом раздумий.
GUID как PK, база Postgresql, для Oracle тоже интересно. В связке с EF.
Мнэ... Let me google it for you, понимаешь. https://www.postgresql.org/docs/current/datatype-uuid.html Вот только про связку с EF ничего сказать не могу.
Let me google it for you
но там нет сравнения различных способов
Это первое, что интересовало.
Второе, что делает EF по умолчанию. Это я уже знаю - оракле: raw, постгрес: uuid
И третье, как как сделать преобразование базы оракле в постгресс с наименьшими затратами если "там есть" Guid.
Не забыть и про изменения в софте. Желательно никаких.
там изначально не дается гарантии на уникальность
"the chances of generating a duplicate GUID : 1 in 2^128;"
пока хватает, да и так уже сделано.
Если не хватает размера ключа
дело разве в этом было, что так сделали или делают?
но там нет сравнения различных способовЭто первое, что интересовало.
Так тебе шашечки или ехать?
Определись какие способы сравнивать собираешься.
Надеюсь, достаточно очевидно что на хранение 128-и битного поля бд потратит туро меньше места чем на строку.
Не забыть и про изменения в софте. Желательно никаких.
В том же EF и подобных ORM должна быть как минимум перегенерина прослойка доступа к БД. А сами вызовы методов прослойки вроде и не меняются.
И третье, как как сделать преобразование базы оракле в постгресс с наименьшими затратами если "там есть" Guid.
Есть какие-то другие преобразования, кроме копирования данных из таблиц с вызовом newguid, newid (или подобного) для каждой новой строки? Неважно, гуиды это или обычный интегер.
Новая БД - новые идентификаторы. Только остальные данные можно полностью скопировать.
кроме непомерной глупости
Это не аргументы, всегда есть плюсы и минусы.
для ГУИДов нет гарантии не повторения
А отчего это должно волновать, с подобной вероятностью, в данном конкретном случае?
А даже если и будет получен не уникальный ид, какой катастрофой это будет нам грозить?
Так тебе шашечки или ехать?
Хотелось бы найти критерии выбора для каждого случая.
Пока есть две вроде 2 группы: строки и цифровая форма.
то на хранение 128-и битного поля бд потратит меньше места чем на строку
Скажем так - недостаток 1, и во всех ли случаях нам это будет интересно?
Какие еще есть?
Из достоинств, как кажется:
- 100% переносимость
- Минимум конвертаций, если пользуем json
- Что вижу то и "пою". Блин, сейчас с ораклом просто катастрофа. При отладке видишь одно, в при просмотре базы совсем другое.
А отчего это должно волновать
------
Я вот не припомню, чтобы в каком-нибудь софте случалось видеть обработку ошибки уникальности первичного ключа...
Судя по вопросу - ключи генерятся не на сервере, а клиентами - т.е. там вообще бардак гарантируется...
какой катастрофой это будет нам грозить?
-----
А что будет результатом выборки при наличии двух и более одинаковых ПК?
А какая именно будет первой?
а я вот не припомню
------
https://it.wikireading.ru/20048
Хотя да, исключения могут быть
-----
Именно так...
В том же EF и подобных ORM должна быть как минимум перегенерина прослойка доступа к БД. А сами вызовы методов прослойки вроде и не меняются.
Поэтому, кстати, и не нужна эта самописная устаревшая херота типа "repository pattern". Максимум, если там какая-то лютая кастомная транзакция с задействованием кучи сущностей - ну пишешь её в отдельную функцию.
А сами вызовы методов прослойки вроде и не меняютсяне меняются. А если народ любит code first?
А это тут причём? Коде фёрст это описание модели, а функционал вы берёте от изкоробочного базового класса с поддержкой EF интерфейсов типа IQueryable, если мне не изменяет память.
Новая БД - новые идентификаторы. Только остальные данные можно полностью скопировать.От подобных заяв волосы дыбом встают
Приведите заявы получше. Я не эксперт - я бы тупо скопировал данные из таблиц с новой генерацией ключей. Вы бы ключи тоже скопировали? А там есть возможность выбирать, будут ключи копироваться или генериться? Как механизм БД распознает, как генерить следующие ключи после вставки кучи готовых? Когда БД сама генерит от начала и до конца, то ей норм, а когда всякие вмешиваются в этот процесс в погоне за призрачными оптимизациями, то могут вознинуть сложности.
На вот попробуй
CREATE TABLE [dbo].[AspNetRoles] ( [Id] NVARCHAR(128) NOT NULL, [Name] NVARCHAR(256) NULL, [NormalizedName] NVARCHAR(256) NULL, [ConcurrencyStamp] NVARCHAR(MAX) NULL, CONSTRAINT [PK_AspNetRoles] PRIMARY KEY ([Id]) ); CREATE UNIQUE INDEX [RoleNameIndex] ON [dbo].[AspNetRoles] ( [NormalizedName] ASC ); INSERT INTO [dbo].[AspNetRoles] ([Id], [Name], [NormalizedName], [ConcurrencyStamp]) VALUES ('27163748-00f8-4725-8d4e-9dce62923f2c', 'TestAdmin', 'TESTADMIN', 'af32e894-1def-4665-b7be-dff048774f1a'); INSERT INTO [dbo].[AspNetRoles] ([Id], [Name], [NormalizedName], [ConcurrencyStamp]) VALUES ('274e474d-a20d-48a6-ab9a-f260a88fec43', 'TestStudents', 'TESTSTUDENTS', 'e8d8fa37-89b5-4f9d-bdc4-476111593ce9'); INSERT INTO [dbo].[AspNetRoles] ([Id], [Name], [NormalizedName], [ConcurrencyStamp]) VALUES ('274e474d-a20d-48a6-ab9a-f260a88fec43','abs','abs','e8d8fa37-89b5-4f9d-bdc4-476111593ce8');
[Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Violation of PRIMARY KEY constraint 'PK_AspNetRoles'. Cannot insert duplicate key in object 'dbo.AspNetRoles'. The duplicate key value is (274e474d-a20d-48a6-ab9a-f260a88fec43).
А это тут причём?
migration каталог желательно исследовать
я бы тупо скопировал данные из таблиц с новой генерацией ключей
Я тоже никак не эксперт в базах, просто есть некоторый опыт, ну вот две таблицы, как будет выглядеть копия?
|PK | | | 1 |Test1| | 2 |Test2| |PK | | | | | 1 |Test1|1|2| | 2 |Test2|1|2|
Я чёт не понял. Если БД используют разные СУБД и исключительно их эксклюзивные фишки, то да, могут возникнуть проблемы. Но если всё подчиняется общему SQL, то их по идее не должно быть. А уж если вообще всё в одной СУБД происходит, то тем более.
Причём тут ваши таблички при преобразовании баз - непонятно. Ну я просто скопирую схему БД в новой СУБД (в том же MS SQL даже команда вроде есть создать скрипт создания БД по уже имеющейся БД) и начну копировать данные. В зависимости от наличия и количества связей с другими таблицами, это будет иметь разную сложность, но в принципе выполнимо же? А если есть встроенные механизмы миграции БД на другие СУБД - то вообще хорошо.
А это тут причём?migration каталог желательно исследовать
А почему нельзя взять последний слепок схемы БД и использовать его? Зачем вам история изменений с незапамятных времён? EF же может генерить схему классов ORM по уже имеющейся БД. А там можете дальше дописывать изменения вашими миграциями.
Я не эксперт, но попробовав немного пописать миграции в EF пришёл к выводу, что через какое-то время там просто нечитаемая лапша. Нафига её копить - протоколирование всех изменений - непонятно. Просто начинаешь новую жизнь с чистого листа при переносе БД и всё.
На вот попробуй
-----
Зачем?
Я и так верю что ты знаешь что у мелкомягких ПК - не нулл и уникален....
И даже подозреваю что в курсе как задизейблить констрайнт на тихую вставку дубликата...
ODBC Driver 17 for SQL Server
-----
У тебя корректная обработка этого исключения есть?
А если поменять драйвер? Взять не ОДБС, а MS SQL (native)...
мелкомягких ПК - не нулл и уникален
странно, а отчего sqlite выдает? UNIQUE constraint failed: AspNetRoles.Id
у мелкомягких научились гады? Ломит проверять все базы, но грю, что не помню другого поведения
У тебя корректная обработка этого исключения есть?
Зачем? достаточно того что в базе не будет дубликатов
Взять не ОДБС, а
давай еще попробуем oledb... может там будет разрешено
все базы, но грю, что не помню
-----
А твое ВСЕ включает не реляционные?
Зачем?
------
И шо? или ничаво ня потяряетси, или тоби пофиг на потери...
давай еще попробуем
-----
Я тебе и так скажу - то, что работает с мелкомягким, не будет работать с ораклом - там отдельные ехцепшены...
и у ОДБС ехсептионы, насколько Я помню, отличаются от мсскл-найтивных...
т.е. - качатся, но только сильно обобщенно...
А твое ВСЕ включает не реляционные?
Нет конечно это уже совсем другая история.
то, что работает с мелкомягким, не будет работать с ораклом
можно и с ораклом попробовать, раз sqlite тебе не подходит, только у меня с локальной базой какие то проблемы были.
ОДБС ехсептион
И много кто сейчас новые проекты на ентом делает? Или даже пользует?
Ты лучше скажи - с постгрессом опыт есть? А то он гад отчего то не любит async запросы из EF, которые получаются как бы параллельно (один запрос начался, "выходим" и заходим в другой). С ораклом никаких проблем не было.
Ты лучше скажи - с постгрессом опыт есть? А то он гад отчего то не любит async запросы из EF, которые получаются как бы параллельно (один запрос начался, "выходим" и заходим в другой). С ораклом никаких проблем не было.
Никаких проблем с potgresql-ем не было. Но не из EF. А в чём проблема-то выраваетя, а то, может, ты незакоммиченные изменения найти не можешь?
А в чём проблема-то
Пока как видится на данный момент, еще нужно дальше исследовать.
Блазор сервер, веб приложение, только чтение, несколько компонент, одна в другой.
Один пользователь, всё локально, один контехт базы.
Данные выдаются как IAsyncEnumerable. Одна компонента начинает асинк запрос на чтение базы, потом, по идее идет дальше, переходит в другую и опять начинает асинк запрос на чтение. Вот этот второй запрос и выдает исключение, что мол, типа нефиг вызывать один контекст их двух разных потоков. Но что то непонятно, откуда несколько потоков при отрисовки компоненты, по идее всё в одном ui потоке должно быть. Да и с ораклом то всё работало и работает, с тем же кодом.
...Осталось еще проверить номера потоков, что бы наверняка знать
Лечится либо задержкой между вызовами, либо переделкой на синхронное чтение из базы. Но ни то ни другое, как то не хочется.
Данные выдаются как IAsyncEnumerable. Одна компонента начинает асинк запрос на чтение базы, потом, по идее идет дальше, переходит в другую и опять начинает асинк запрос на чтение. Вот этот второй запрос и выдает исключение, что мол, типа нефиг вызывать один контекст их двух разных потоков. Но что то непонятно, откуда несколько потоков при отрисовки компоненты, по идее всё в одном ui потоке должно быть. Да и с ораклом то всё работало и работает, с тем же кодом.
А с чего бы второму потоку не взяться, если асинхронные операции могут выполняться как в одном потоке, так и в разных?
А вы уверены, что компоненты при отрисовке всё в одном потоке делают, а не каждый свой создаёт? State changed же для каждого компонента (и его подкомпонентов) отдельно выполняется, а значит каждый сам себя перерисовывает.
А в Оракле точно всё асинхронно работало, или там синхронно всё выполняется?
Но что то непонятно, откуда несколько потоков
------
Мне вот непонятно почему ожидается один поток... при асинхронике.
по идее всё в одном ui потоке должно быть.
-----
Хи-хи...
Это ты еще с мелкомягкой многопоточностью в ДотНет не работал...
Там - шикарно... создаешь поток, все нормально... запускаешь, все нормально... получаешь данные, все нормально... пытаешься что-то сделать в созданном потоке - облом... Нее, все работает и управляется, вот только не в том потоке что тобою создан... как? а хрен его знает... чтобы получить что нужно было откатился до примитивного потока - тогда получилось...
не вот непонятно почему ожидается один поток... при асинхронике.
дай описание где написано про много
https://stackoverflow.com/questions/37419572/if-async-awai...
Там - шикарно... создаешь поток, все нормально... запускаешь, все нормально... получаешь данные, все нормально... пытаешься что-то сделать в созданном потоке - облом... Нее, все работает и управляется, вот только не в том потоке что тобою создан... как? а хрен его знает... чтобы получить что нужно было откатился до примитивного потока - тогда получилось...
Это случайно не про обновление UI из рабочего потока?
Данные выдаются как IAsyncEnumerable. Одна компонента начинает асинк запрос на чтение базы, потом, по идее идет дальше, переходит в другую и опять начинает асинк запрос на чтение. Вот этот второй запрос и выдает исключение, что мол, типа нефиг вызывать один контекст их двух разных потоков. Но что то непонятно, откуда несколько потоков при отрисовки компоненты, по идее всё в одном ui потоке должно быть. Да и с ораклом то всё работало и работает, с тем же кодом....Осталось еще проверить номера потоков, что бы наверняка знать
Гм. Это какой-то шарпный/EF геморрой. Тут я не помогу. Так-то у постгреса нет никаких проблем с паралелльным доступом. Ну, если кто-то с какого-то перепугу не выставил isolation level в serializable конечно.
P.S. Ну и если мелокомягкие не изобрели какое-то очередное гавно вроде замыканий по ссылке, то конечно же вызванные черезе await-async методы могут выполнятся в разных потоках. Какой-то пул потоков должен быть.
Лечится либо задержкой между вызовами, либо переделкой на синхронное чтение из базы. Но ни то ни другое, как то не хочется.
Попробуйте ещё виртуализацию на клиенте сделать, чтобы запрашивалась только та часть, что сейчас отображается (с запасом в начале и конце списков). Тогда запросы будут быстрые и данных будет передаваться немного. Может, они и не пересекутся. Обычно в популярных Blazor-фреймворках такая виртуализация из коробки есть.
Зачем тут вообще IAsyncEnumerable не понял. Первый раз эту штуку встречаю. Если запросы маленькие, может, можно и без этого обойтись?
Тестовый проект очень простой:
Главная компонента, вызывает вложенную компоненту, та еще одну. Код 1й вложенной компоненты, остальное тоже самое практически
Child 1 Component enter await thread @idOfRenderingThreadIn continue thread @idOfRenderingThreadOut <Child2Component></Child2Component> @code { private int idOfRenderingThreadIn; private int idOfRenderingThreadOut; protected override async Task OnInitializedAsync() { idOfRenderingThreadIn = System.Threading.Thread.CurrentThread.ManagedThreadId; await base.OnInitializedAsync(); await Task.Delay(10); idOfRenderingThreadOut = System.Threading.Thread.CurrentThread.ManagedThreadId; } }
Результат выполнения
и нашлось: что только для Blazor server повторный вход в компоненту может быть из другого потока (точнее речь идет об отрисовке)
Ошибка:
error: System.InvalidOperationException: A second operation was started on this context instance before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.
По ссылке ничего полезного не нашлось для данного случая.
То бишь отчего не работает, стало вроде понятно. А вот отчего Оракл работает еще непонятно.
Попробуйте ещё виртуализацию на клиенте сделать
не поможет, и не нужно. Относительно мало данных
Если запросы маленькие, может, можно и без этого обойтись?
отрисовка все замедляется, а при первом запросе в день будет совсем плохо.
IAsyncEnumerable
Тоже не любитель но иногда полезно
лечится только созданием/уничтожением контекста прямо в запросе.
public class FooByIdDataLoader { private readonly IDbContextFactory _dbContextFactory; public FooByIdDataLoader(IDbContextFactory dbContextFactory) { _dbContextFactory = dbContextFactory; } protected override async Task> LoadBatchAsync(IReadOnlyList keys, CancellationToken ct) { await using ApplicationDbContext dbContext = _dbContextFactory.CreateDbContext(); return await dbContext.Foos .Where(s => keys.Contains(s.Id)) .ToDictionaryAsync(t => t.Id, ct); } }
Хорошо что ты сказал, хотел показать другое, что раньше видел, а тут новое.
Слева сидим в exception, а справа фигня, что драйвер еще "секретно" делает видимо, тогда это объясняет отчего с ораклом работает.
Если бы еще понять что это должно значить...
Черт, забыл что картинку только из файла можно вставить, исправил. Слева там, где exception при чтении с базы, справа, что в "паралельном" стеке.
срабатывает регулярно
Увы, радость была напрасной. Всё исключительно что приведено исключительно в тестовом приложении сейчас получается, на деле как и раньше было, два async запроса по чтению.
И никакие исправления не получаются. Кто то додумался использовать аж 4 глобальных параметра, каждый из которых грузится из базы.
https://learn.microsoft.com/en-us/aspnet/core/blazor/compo...
И любые изменения приводят к тому, что один из них, по крайней мере, становится нулем. Контексты как я выше, в примере сделал, тоже пока не получается разделить, там иерархия контекстов.
Похоже мелкими изменениями не обойтись