Як я реалізую базу даних / таблицю як стек


11

У мене є стан-машина, яка повинна натискати / висувати деякі імена файлів для різних користувачів. Я б традиційно використовував стеки як вибір структури даних, але це потрібно зробити за допомогою бази даних, оскільки у мене немає способу зберегти структуру даних між вхідними веб-запитами.

Мені було цікаво, який би був хороший спосіб реалізувати функціонал стека за допомогою баз даних?

Мені потрібно підтримати:

  • push (ім'я файлу, користувач): натисніть ім’я файлу для користувача
  • pop (користувач): Поп найпопулярнішого імені файла для користувача

Редагувати :

Я прототипую ідею, і тому я використовую sqlite3 з python.

Спасибі!


чи очікуєте, що той самий користувач матиме кілька одночасних з'єднань? які обсяги? який ДБ двигун теж будь ласка?
gbn

@gbn Зрештою, той самий користувач може мати одночасні з'єднання. Але наразі я прототипую ідею, і я припускаю єдине з'єднання на кожного користувача
brainydexter

@brainydexter Я дуже хотів би знати, що ти намагаєшся робити. Я відчуваю, що ви можете створити неправильне рішення своєї проблеми. Ви можете розглянути питання про свою проблему та запропонувати найкращий шлях для її вирішення. Реалізація стека як таблиці бази даних звучить як погана ідея.
ксенотеррацид

@xenoterracide: Загальний намір того, що я намагаюся зробити в SO: stackoverflow.com/questions/5145051/… Стек не спрацював повністю, тому я все ще шукаю рішення для цього.
brainydexter

1
@brainydexter насправді не здивував, SQL - жахлива мова для реалізації стека, оскільки за реляційним визначенням набір не є упорядкованим, тому ваш стек не матиме порядку, і вам доведеться його сортувати. Можливо, частиною вашої проблеми є те, що ви говорите людям, на що ви хочете відповісти, і ви запитуєте, як. Замість того, щоб сказати їм, в чому проблема, і запитати в чому. Навіть ваше запитання про те призводить до відповіді на щось конкретне. Спробуйте попросити рішення, про яке ви не будете думати.
ксенотеррацид

Відповіді:


6

Якщо ви запитуєте, яку базу даних використовувати, це дійсно залежить від особистих уподобань і того, що ви хочете від неї використовувати. Оскільки я лише знайомий з MySQL, я відповім на іншу частину питання, припускаючи MySQL:

ви хочете використовувати, INNODBоскільки ваша таблиця буде інтенсивною для запису, а для великих таблиць блокування рядків INNODB буде рятувати життя MyISAM.

Що стосується дизайну столів, то, здається, вам потрібен лише один стіл:

CREATE TABLE `wordpress`.`<table_name>` (
`id` smallint(4) NOT NULL AUTO_INCREMENT UNSIGNED,
`user` varchar(30) NOT NULL,
`filename` varchar(255) NOT NULL,
`date_insert` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE `userFile`(user, filename)
) ENGINE=`InnoDB`;

Я перейшов із довільним стовпчиком 'id', встановленому AUTO_INCREMENTтому, що первинний ключ реплікується у кожному записі кожного індексу. Таким чином, виконання первинного ключа (користувача, імені файлу) може спричинити проблеми з продуктивністю, якщо ваші імена файлів надзвичайно довгі.

Розмір стовпця "id" залежить від того, наскільки велика ваша таблиця буде рости. Без підпису Smallint дасть вам 65k рядків.

Користувач і назви файлів - varchar, тому що вони, як я вважаю, різко відрізнятимуться по довжині.

Це date_insertлише спосіб замовити результати залежно від того, коли вони були вставлені (корисно для вашого POP)


Я думав зробити комбінацію (ідентифікатор, користувач) як основний ключ, оскільки я хотів би натиснути або попсувати на основі користувача. Як ти гадаєш ? Також для операції POP не було б краще знайти запис для користувача з максимальним ідентифікатором?
brainydexter

@brainydexter dev.mysql.com/doc/refman/5.0/en/innodb-restrictions.html має деякі обмеження щодо автоматичного збільшення (у деяких рідкісних випадках воно повторно використовуватиме "нижчі" значення самовдосконалення). тому що це можливість, я перейшов із полем date_insert. Що стосується використання (id, user) в якості основного ключа, немає сенсу, крім того, щоб зайняти більше місця. Ідентифікатор однозначно ідентифікує рядок. просто "user" сам по собі не ідентифікує рядок, тому ви можете просто мати унікальний індекс на "userID" замість унікального (user, name file), якщо хочете.
Дерек Дауні

6

Якщо ви розглядаєте базу даних Oracle, вам слід подумати про використання розширеної черги з LIFO (останнім у першому випадку) схемою декету .

На самому базовому рівні черги один виробник передає одне чи більше повідомлень в одну чергу. Кожне повідомлення видаляється та обробляється один раз одним із споживачів. Повідомлення залишається у черзі, поки споживач не скасує його або повідомлення закінчиться. Виробник може встановити затримку до того, як повідомлення буде доступне для споживання, і час, після якого повідомлення закінчується. Так само споживач може зачекати, коли намагається видалити повідомлення, якщо повідомлення не доступне. Агентська програма або програма може виступати як виробником, так і споживачем.


класичне налаштування виробника / споживача. Дякую за інформацію, я пам’ятаю про це.
brainydexter

Сподіваємось, MySQL отримає певну функціональність Adance Queue тепер, коли Oracle "володіє" mysql ...
Дерек Дауні

1
@DTest: звичайно, також існує чітка ймовірність того, що mySQL тепер має меншу ймовірність отримати розширені функції, тому Oracle може розмежувати вільне програмне забезпечення та те, за що вам доведеться платити.
Джо

@Joe дякую, що зіпсував мій вихідний з цією думкою!
Дерек Дауні
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.