Здравствуйте, не давно узнал про приведение таблицы в 3 НФ и захотелось попробовать на практике ее спроектировать [Удобнее для данного примера, почему-то мне показался Access] и использовать [Через плагин на SourcePawn]. Получилась такая схемка (Это же точно 3 нф
)
Я заполнил таблички некоторыми записями для большего понимания проблемы:
С какой проблемой я столкнулся и почему я пишу сюда? - Мой плагин выполняет роль ядра, к которому можно написать модуль, но проблема в способе идентификация значения. Допустим у нас имеются два модуля - один из них - при заходе игрока обновляет его текущий ник, а другой - дату последнего захода.
Для сохранения значений в БД используется
Но для того, чтобы обновить данную запись - необходимо знать `feature_id` и тут встает у меня вопрос, ведь я могу пойти двумя путями:
1) При старте плагина и коннекта его к БД - загружать все значения из`authsystem_features` в ArrayList g_hFeatures, который хранит enum struct FeatureInfo =>
Тогда при использовании
Мне необходимо будет делать что-то типа такого, каждый раз, когда я хочу обновить значение:
Но мне не нравится хранить по факту всю таблицу `authsystem_features` в плагине, по этому, можно пойти по второму способу:
2) Обновлять значение простым объединением двух таблиц - Данный способ мне действительно симпатизирует , но смущает - что такой запрос, по моему мнению, не является эффективным и правильным и нужно делать как-то по другому, по этому и была создана эта тема, чтобы подтвердить мои опасения, или же их развеять

Я заполнил таблички некоторыми записями для большего понимания проблемы:
С какой проблемой я столкнулся и почему я пишу сюда? - Мой плагин выполняет роль ядра, к которому можно написать модуль, но проблема в способе идентификация значения. Допустим у нас имеются два модуля - один из них - при заходе игрока обновляет его текущий ник, а другой - дату последнего захода.
Для сохранения значений в БД используется
C-подобный:
native void AuthSystem_SetFeatureValue(int iClient, const char[] sFeature, const char[] sValue);
Но для того, чтобы обновить данную запись - необходимо знать `feature_id` и тут встает у меня вопрос, ведь я могу пойти двумя путями:
1) При старте плагина и коннекта его к БД - загружать все значения из`authsystem_features` в ArrayList g_hFeatures, который хранит enum struct FeatureInfo =>
C-подобный:
enum struct FeatureInfo
[
int id;
char feature[32];
]
C-подобный:
native void AuthSystem_SetFeatureValue(int iClient, const char[] sFeature, const char[] sValue);
C-подобный:
int FindIndexFromName(const char[] sFeature)
{
FeatureInfo info;
for(int x = 0; x < g_hFeatures.Length; x++)
{
g_hFeatures.GetArray(x, info, sizeof(FeatureInfo));
if(!strcmp(sFeature, info.feature))
{
return x;
}
}
return -1;
}
void SaveValue(int iClient, const char[] sFeature, const char[] sValue)
{
int index = FindIndexFromName(sFeature);
if(index == -1)
{
return;
}
char sQuery[256];
FormatEx(sQuery, sizeof sQuery, "UPDATE `authsystem_players_features` SET `value` = '%s' WHERE `player_id` = %d AND `feature_id` = %d", g_Player[iClient].id, index);
DB_TQueryEx(sQuery);
}
Но мне не нравится хранить по факту всю таблицу `authsystem_features` в плагине, по этому, можно пойти по второму способу:
2) Обновлять значение простым объединением двух таблиц - Данный способ мне действительно симпатизирует , но смущает - что такой запрос, по моему мнению, не является эффективным и правильным и нужно делать как-то по другому, по этому и была создана эта тема, чтобы подтвердить мои опасения, или же их развеять
C-подобный:
void SaveValue(int iClient, const char[] sFeature, const char[] sValue)
{
char sQuery[256];
FormatEx(sQuery, sizeof sQuery, "UPDATE `authsystem_players_features` p INNER JOIN `authsystem_features` f ON f.`feature` = '%s' SET p.`value` = '%s' WHERE p.`player_id` = %d AND p.`feature_id` = f.`id`", sFeature, sValue, g_Player[iClient].id);
DB_TQueryEx(sQuery);
}