2

Я новичок MySQL и ищу решение следующей задачи:Mysql выводит внешний ключ для случайных запросов

Я хотел бы создать CMS с CppCMS, которые должны быть способны иметь модули. Поскольку я хочу уменьшить вероятность (случайного) доступа к конфиденциальным данным, мне нужен модуль, который обрабатывает доступ к данным и права. Поскольку этот модуль должен быть не осведомлен о структурах данных, созданных другими модулями, я бы хотел, чтобы он вывел владельца данных через внешний ключ отношений. Моя идея заключалась бы в поиске пути (по внешним ключам), который связывает строку с идентификатором пользователя.

Сложите: Что я пытаюсь сделать

  1. Принимая случайный запрос, определить измененные строки
  2. для изменяемых строк определяют отношения/путь (через внешние ключи) к user/userid (столбец в существующей таблице)
  3. возвращает только строки, для которых может быть определено отношение, и выполняется условие (например, идентификатор пользователя, найденный в соответствующем запросе, совпадает с фиксированным идентификатором пользователя, таким как пользователь, система)

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

Моя проблема/вопрос:

  1. есть ли существующее решение/Better подход к проблеме? Подготовленные утверждения не будут делать трюк, так как я не знаю всех данных/запросов заранее.

  2. Как получить отношения с внешним ключом? Есть ли другой способ, кроме «SHOW CREATE TABLE», а затем синтаксический анализ строки результата?

  3. Как определить строки, которые будут затронуты, без их модификации? Я хотел бы отфильтровать этот набор после определения, могу ли я связать его с текущим пользователем (а не с пользователем mysql, но с системным пользователем).

Могу ли я попытаться выполнить запрос, а затем выбрать строки влияния, и если я определяю нарушение доступа, просто выполните откат? Проблема с этим: как сделать изменения в подмножестве строк, для которых оно является законным (например, я пытаюсь изменить 5 строк, может только изменить 2, как только изменить те 2). Одна из идей заключалась в поиске способа создания временной таблицы с набором результатов; это решение имеет несколько недостатков: отношения внешних ключей не могут быть временными таблицами, они «потеряны».

P.S .: Я кодирую в C++, поэтому я предпочел бы рекомендации, совместимые с cpp-совместимостью, однако я открыт для других предложений. В то время как googling я наткнулся на доктрину, и я сейчас изучал ее. P.P.S .: База данных InnoDB двигатель (должен из-за внешних ключей)

UPDATE: Объяснение Попытка Часть 2: Я пытаюсь отфильтровать collumns пользователю разрешено видеть из таблиц. Для этого я хотел бы найти соединение в базе данных по внешним ключам (по внешним ключам я гарантирую, что могу получить все данные по соединениям, и они представляют собой намек на то, какие столбцы я должен присоединиться).Поскольку я планирую сложную систему (например, форум), я не хочу объединять все данные во временной таблице и запускать запрос пользователя на них. Я бы предпочел оценить userquery и проверить результат, если я могу сопоставить его с соединением с идентификатором пользователя. Например, я мог бы использовать это, чтобы обеспечить, чтобы кнопка редактирования была включена только для сообщений, созданных пользователем. (Я знаю, что есть более простые способы сделать это, но я в основном хочу, чтобы программисты могли писать свои собственные запросы, не предоставляя им возможность редактировать или просматривать данные, которые им не позволяют видеть. Мое предположение заключается в том, что программист не является evildoer, но просто забывая о ограничениях, поэтому я хочу обеспечить их исполнение в программном обеспечении).

Получение здесь будет довольно хорошим, но у меня есть еще более сложная потребность.

Первый базовый пример. Скажем так, как и facebook, и всем друзьям человека разрешено видеть его фотографии.

pictures = id **userid** file (bool)visibleForFriends album 
friendship = **userid1** **userid2** 
users = userid 

То, что я хочу, чтобы случиться:

  1. входной программатор "SELECT * FROM фотографии, где альбом = 2"
  2. система получает все соответствующие записи (например, набор идентификаторов)
  3. системы видит внешний ключ пользователя, пытается сопоставить текущий идентификатор пользователя с изображениями userid, добавляет все совпадения с возвращаемой частью результата
  4. Системные уведомления special visibleForFriends колонка
  5. Система пытается всего определится все друзья (SELECT userid1 FROM дружбой WHERE userid2 = currentUserID присоединиться (надо читать на соединения) ВЫБОР userid2 от дружбы WHERE userid1 = currentUserID)
  6. Система добавляет все строки, где visibleForFriends is true и pictures.userid = Результат от 5.

В то время как часть Дружбы - это дополнительный код (я думаю, что можно сделать, если igot начался с первого бита), мне все же нужно выяснить, как автоматически следовать за иностранным для просмотра соединения. Не обращая внимания на особый случай дружбы (особый случай), я хотел бы, чтобы система работала на этом, а также:

pictures = id **albumid** file (bool)visibleForFriends album 
albums = id **userid** 
users = userid 

Теперь система должна идти фотографии. albumid ==> albums.id -> альбомы. userid ==> users.userid.

Надеюсь, что примеры немного выяснили вопрос. Одна из проблем заключается в том, что в первой части примера (ввод запроса программиста) я не хочу, чтобы «DELETE *» вступал в силу с тем, что не принадлежит пользователю. Поэтому я должен отфильтровать, какие строки фактически удалить.

ответ

1

В ответ на часть вашего ответа (часть 1), предоставляя пользователь Mysql вам доступ к базе данных с имеет право доступа к information_schema, то вы можете использовать следующий запрос, чтобы понять существующую внешние ключевые отношения в конкретной базе данных:

SELECT 
    TABLE_NAME, 
    COLUMN_NAME, 
    REFERENCED_TABLE_NAME, 
    REFERENCED_COLUMN_NAME 
FROM 
    information_schema.KEY_COLUMN_USAGE 
WHERE 
    TABLE_SCHEMA = 'dbname' AND REFERENCED_COLUMN_NAME IS NOT NULL; 

Я немного смущен частью 2 и не уверен, как дать соответствующий ответ этому разделу. Надеюсь, вы найдете приведенный выше запрос полезным, хотя в вашем проекте!

+0

Большое спасибо, я попробую это, как только я вернусь домой в свою базу данных. Я попытался привести пример в своем вопросе (из жирного обновления вниз) – ted

0

Есть ли существующее решение/Лучший подход к проблеме?

Да, я так думаю. Вы описываете базу данных с несколькими арендаторами. В базе данных с несколькими арендаторами, в которой пользователи совместно используют таблицы (также называемые «общим всем»), каждая таблица должна иметь столбец для идентификатора пользователя. По сути, каждая строка знает своего владельца.

Это значительно упростит ваш SQL, поскольку вам не требуется объединение, чтобы определить, к какой строке принадлежит. это, вероятно, ускорит ваш SQL тоже.

This SO answer имеет достойное резюме проблем и альтернатив.

+0

Я думаю, что он сильно отличается от мутантного после того, как он превратился в статью. Не следует рассматривать, например, Facebook как мутантный или я ошибаюсь? (Друзья и владелец могут получить доступ к определенным данным, тогда как другие данные видны всем). Спасибо хотя за указатель. – ted

Смежные вопросы