Вопрос по чтение и сравнению
#1

Привет всем. Нужна небольшая помощь.
Вообщем делаю систему которая позволяет создавать пользователю проекта до 2 аккаунтов.
Вообщем создает пользователь в UCP. Далее он может создать до 2 игровых аккаунтов.
Меня интересует как правильнее будет сделать систему для чтение и сравнение данных.
Я думаю что когда создается пользователь в UCP. сохраняется данные такие как Логин, Пароль. Почта. IP и создает два столбца для с игровыми никами пользователя.
Далее при обычная регистрация аккаунта. Ник аккаунта записывает в столбец 1 или 2 в зависимости от того какой игровой аккаунт создает. А так же в каждый аккаунт пользователя записывать имя пользователя под которым он был создан.
Далее игрок заходит на сервер. и вот тут я думаю делать чтение из двух таблиц. То есть берем Имя пользователя= Ником игрового аккаунта. Далее по стандарту. (авторизация и.т.д)
Как думаете такой подход норм будет ? или есть предложение по лучше.
Reply
#2

Две таблицы: аккаунты и персонажи.

Структура таблицы аккаунтов:
PHP Code:
id логин пароль | ... | ID первого персонажа ID второго персонажа 
В двух последних столбцах хранятся ID строк из второй таблицы, а не ники.

Структура таблицы персонажей:
PHP Code:
id ник | ... 
Этот вариант оптимален для ситуации, когда у тебя есть конкретное число персонажей на 1 аккаунт.
Reply
#3

А если будет такая делема, что один из аккаунтов удалиться, из базы данных, а потом создается новый, ведь будут не ровные id
Reply
#4

Эмм, и что? Ты вообще не должен смотреть на порядок ID. ID нужен сугубо для быстрой выборки нужных строк, без поиска по нику.
Reply
#5

Все понял твой вариант. Изначально не так картинку сложил
Reply
#6

а что если сделать так
Таблица пользователей
ID|Логин|пароль|почта

ID ставим auto кремат что ли как то так :d

а в таблицу с аккаунтами записываем ID пользователя ?
как такой вариант
Reply
#7

Эмм, тебе ведь нужно связать аккаунт, под которым игрок авторизируется, с персонажами. Ты и без того будешь выгружать данные аккаунта после авторизации. Потому логичнее хранить ID персонажей там же, чтоб поиск персонажей, которых будет в два раза больше, чем аккаунтов, происходил с минимальными затратами.
Reply
#8

Профиль:
ID (ауто инкремент, примари кей), почта, скилл, деньги и тд.

Аккаунты:
ID (ауто инкремент. Данный столбец по желанию), Ник, ПрофильID (форейнг кей с отсылкой на ID из профиля).
ID (ауто инкремент. Данный столбец по желанию), Ник, ПрофильID (форейнг кей с отсылкой на ID из профиля).
ID (ауто инкремент. Данный столбец по желанию), Ник, ПрофильID (форейнг кей с отсылкой на ID из профиля).


Я бы сделал так и только так.
1) Не за чем устраивать огород с кучей ключей в одной строке.
2) Удобство чтения.
3) В случае чего можно очень быстро чтот поправить, сделать удобно выборку и тд.
4) Неограниченное число персонажей на 1 аккаунт. Лимит ставишь в коде. В любое время можно изменить лимит 1 значением всего лишь.


А насчет быстроты выборки, есть LIMIT %d
Reply
#9

Quote:
Originally Posted by Johhnyllll
View Post
Есть ли разница по скорости поиска по ID и нику?
Особенно когда в БД около 10к аккаунтов?
Дополню ответ выше простым рассуждением:
Строка состоит из символов. Символ хранится в виде числа. Следовательно, когда ты сравниваешь строки, ты сравниваешь определённый набор чисел, количество которых зависит от длины строки.
Ну а когда ты просто сравниваешь 2 числа, ты сравниваешь только 2 числа
Reply
#10

Quote:
Originally Posted by KrYpToDeN
View Post
Профиль:
ID (ауто инкремент, примари кей), почта, скилл, деньги и тд.

Аккаунты:
ID (ауто инкремент. Данный столбец по желанию), Ник, ПрофильID (форейнг кей с отсылкой на ID из профиля).
ID (ауто инкремент. Данный столбец по желанию), Ник, ПрофильID (форейнг кей с отсылкой на ID из профиля).
ID (ауто инкремент. Данный столбец по желанию), Ник, ПрофильID (форейнг кей с отсылкой на ID из профиля).


Я бы сделал так и только так.
1) Не за чем устраивать огород с кучей ключей в одной строке.
2) Удобство чтения.
3) В случае чего можно очень быстро чтот поправить, сделать удобно выборку и тд.
4) Неограниченное число персонажей на 1 аккаунт. Лимит ставишь в коде. В любое время можно изменить лимит 1 значением всего лишь.


А насчет быстроты выборки, есть LIMIT %d
Если не стоит задачи сделать неограниченное количество аккаунтов, то делать так - сомнительное решение.

Представим, что у нас есть таблица с миллионом аккаунтов и мы разрешим игрокам создать до 10 персонажей на один аккаунт.
Следовательно, у нас получаются такие результаты:
PHP Code:
Таблица аккаунтов 1.000.000 записей
Таблица персонажей 
10.000.000 записей 
В моём случае, чтоб найти всех персонажей игрока (факт их наличия), достаточно просто найти одну запись в таблице аккаунтов и из неё выгрузить нужные данные.
В твоём случае придётся делать запрос сначала в таблицу с миллионом записей, чтоб узнать ID аккаунта, а потом уже запрос в таблицу с 10-ю миллионами записей (мы будем это делать всякий раз, когда у игрока меньше 10 персонажей или если персонажи игрока находятся последними в списке и никакой LIMIT тут не исправит ситуацию). При этом, чтоб узнать, создал ли игрок вообще персонажей и если создал, то сколько их, нам придётся прошерстить все 10 миллионов записей. А данная информация будет нужна довольно часто (как минимум, когда игрок открывает список персонажей) и в моём случае мы всё так же работаем с одной строкой из таблицы аккаунтов, не трогая таблицу персонажей.


В итоге, как видно, твоя реализация имеет кучу неоправданных действий для таблицы лишь ради того, чтоб иметь возможность "на лету" увеличивать число персонажей для одного аккаунта (что вряд ли будет полезно). А с учётом того, что ID аккаунта в таблице персонажей - ни разу не уникальное значение, какая-то более-менее серьёзная выборка, которая заставит MySQL создавать временные таблицы для хранения промежуточных данных, может ещё сильнее замедлить запросы.

ИМХО, уж лучше нагородить 2/5/10/20 дополнительных столбцов под персонажей в таблице аккаунтов (или же создать третью таблицу под них, если вы настолько эстеты), но точно знать сколько персонажей создано, под каким номером строки они находятся и свести к минимуму обращение к "тяжёлой" таблице, чем иметь ненужную псевдо-гибкость и, при этом, заставлять MySQL всякий раз проверять кучу записей.
Тем более, что таблица с аккаунтами при таком раскладе и так будет хранить лишь самую общую инфу, по типу пароля, почты и всякий инфы для защиты аккаунта, следовательно, хранение каждого персонажа в отдельном столбце никак негативно не скажется на таблице даже с визуальной части.



UPD: Пройдусь более подробнее по пунктам

Quote:
Originally Posted by KrYpToDeN
View Post
2) Удобство чтения.
3) В случае чего можно очень быстро чтот поправить, сделать удобно выборку и тд.
Как выше уже описал, удобство если и будет, то только для скриптера. Для MySQL же наоборот количество действий увеличится пропорционально. Крайне сомнительно в данном случае жертвовать быстродействием ради того, чтоб запросы стали на 10 символов короче, ибо висящая БД = висящий сервер (по крайней мере жалобы на лаги вы точно себе обеспечите от игроков).

Quote:
Originally Posted by KrYpToDeN
View Post
В любое время можно изменить лимит 1 значением всего лишь.
В предложенном мной варианте так же можно оформить код так, чтоб увеличение лимита занимало лишь одно действие. Точнее, два: изменение константы в коде и создание нужного числа столбцов (хотя и создание/удаление столбцов можно спокойно автоматизировать при старте сервера. Правда, вряд ли все усилия будут оправданы, так как лимит если и будет изменяться, то пару раз за всю жизнь сервера и проще вручную вносить изменения в структуру базы, чем писать для этого кучу дополнительного кода, который будет 99% времени срабатывать в холостую). Так что сомнительный плюс.
Reply
#11

Quote:
Originally Posted by Eims
View Post
Таблица персонажей - 10.000.000 записей[/PHP]
В моём случае, чтоб найти всех персонажей игрока (факт их наличия), достаточно просто найти одну запись в таблице аккаунтов и из неё выгрузить нужные данные.
Тебе в любом случая придется прогонять таблицу с 10 лямами значений. Для быстроты выборки есть индексы. И MySQL явно рассчитан на работу с таким колвом записей
Reply
#12

Quote:
Originally Posted by cm666
View Post
Тебе в любом случая придется прогонять таблицу с 10 лямами значений. Для быстроты выборки есть индексы. И MySQL явно рассчитан на работу с таким колвом записей
В том и дело, что в моём случае мы будем заранее знать сколько строк нужно найти и под каким ID они находятся, чем мы сразу закроем ряд вопросов, которые требовали бы обращения к таблице с 10 миллионами записей + поиск будет проходить по уникальному индексу, что сведёт количество проверок для MySQL к минимуму (как минимум, на одну проверку меньше). Не говоря уже о ситуациях, когда нам изначально нужно работать с конкретным персонажем.
+ не будем забывать о том, что при выборке нельзя использовать больше одного индекса в условии, что может сильно подпортить кровь при составлении сложных запросов в случае, если накрутить бессмысленный индекс на поле с ID аккаунта. Можно, конечно, создавать составные индексы, но это лишь впустую раздует размер таблицы (напомню, что основной плюс всей этой затеи - отсутствие нужды создавать дополнительный столбец для хранения ID персонажа, что автору и не нужно, судя по тому, что он чётко указал количество персонажей).

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

UPD: тут ещё можно вспомнить, например, про кластерные индексы, что в моём случае так же ускорит работу с данными, но это уже лирика. Собственно, дальше нет смысла эту тему продолжать. Кто желает стрелять в собственную ногу, оправдывая это "гибкостью" (хотя как выше уже писал, в моём варианте так же можно добиться гибкости) - ваше право. Но отрицать то, что конкретизация положительно влияет на скорость работы с данными - глупо, хотя, опять же, это ваше право. Уточню лишь, что никто не утверждает, будто вариант, предложенный KrYpToDeN, станет каким-то смертельным и что его ни в коем случае нельзя использовать. Речь лишь о том, что нужно разумно использовать ресурсы и тратить их на решение конкретных задач, а не пытаться решить то, что и решать пока не требуется (да и вряд ли потребуется). И то, что предлагаете вы - неоправданная трата ресурсов (как в плане памяти, так и в плане скорости обработки запросов) на функционал, который не будет использоваться автором.

UPD2: Несомненно, если стоит задача написать систему с неограниченным числом персонажей, то вариант KrYpToDeN будет гораздо оптимальнее. Но такой задачи не стоит и у нас есть вполне вменяемое количество персонажей, которых гораздо проще хранить в таблице с аккаунтами, а не терзать всякий раз таблицу персонажей лишь затем, чтоб понять, создал ли игрок хоть одного персонажа или нет.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)