Ещё одним полезным плагином для Firefox — MeasureIt. Как не трудно догадаться — это линейка для замеров в пикселях.
Найти можно здесь: www.kevinfreitas.net/extensions/
В таком случае вся полемика вашего комментария развернулась лишь благодаря подсознательной подмене слов и значений. Судя по ответам многие восприняли «не истинна», как «ложь». Потому как опровергнуть ваше высказывание не представляется возможным ввиду отсутствия в нём информации. Тема минусов не понятна. Для программистов: null!=true и null!=false
«Следовательно, любая аксиоматика не является истинной.»
Это не правильный вывод, вводящий вас в последующие заблуждения.
Если аксиому не возможно доказать, то это совсем не значит, что она ложна. Дело в том, что логика бывает разной и использовать тут логику (NOT TRUE) EQUALS FALSE. Хоть и основа логики всегда одинакова TRUE NOT EQUALS FALSE. Правильным выводом об аксиоме будет (NOT TRUE) AND (NOT FALSE) = NOT (TRUE OR FALSE).
Пример ошибочности применения бинарной логики: Утверждение: Не бывает рыжих слонов. Не правильный вывод (сделанный подобно вашему): Все кто не рыжий — слон. Правильный вывод: Если слон, то не рыжий.
Зависит от размеров таблиц. В моём проекте пользователей не много (меньше 5К) и никаких проблем быстродействия или нагрузки не возникало. К тому же правильное использование индексов (они ведь есть, просто работают в данном решении не на 100%) и построение с учётом execution plan и cost function решат большинство проблем со сложными запросами. Главное понимать, когда стоит применять флаги, а когда нет.
Целей получается не так уж и мало, а делать профиль для каждой довольно не удобно. К тому же логаут-логин на моём компутере может занять пару минут, а потом опять те же двадцать пять для возвращения в обычный режим :/
Как пользователю хилого (уже) ноутбука приходилось всегда в ручную включать и выключать системные процессы в зависимости от задачи. Думаю ваша программа поможет мне не только создать настройки «для дома» и «для офиса», но и добавить режим медиа центра, режим для игр (если ещё и гамма коррекцию позволяет менять — вообще супер), режим для нет сёрфинга и т.д! А то частенько фильмы подтормаживают если запущенны сервисы IIS, SQL, MDM, SystemUpdate...
LIKE '%%' будет намного более тяжёлой операцией, да и к тому же сокращает возможности оптимизации.
Во всяком случае поиск по маске становиться сложней (допустим нам надо найти подписчиков на тип сообщений 2 и 3): SELECT * FROM tblUsers WHERE alerts like '%3%' and alerts like '%2%'
А с флагами решение частично использовало бы преимущество индекса, не имело бы значение в каком порядке были добавлены подписки и сколько ещё подписок существует у пользователя: SELECT * FROM tblUsers WHERE tblUsers.alert = 6 OR (tblUsers.alert & 6) > 0
или можно пойти на шаг дальше (в зависимости от cost-function): SELECT * FROM (SELECT * FROM tblUsers WHERE tblUsers.alert>=6) as tblUsers1 WHERE (tblUsers1 .alert & 6) > 0
Из-за использования подзапроса результат (tblUsers1 ) не будет иметь индексов, но так как в битовой операции они нам всё равно не помогали, то сокращение количества этих самых битовых операции сыграет положительную роль.
Ещё на шаг дальше: SELECT * FROM (SELECT * FROM tblUsers WHERE tblUsers.alert=6 or tblUsers.alert > (SELECT MAX(alertID) FROM tblAlerts)) as tblUsers1 WHERE tblUsers1 .alert = 6 OR (tblUsers1 .alert & 6) > 0
Так как таблица флагов (tblAlerts) подразумевает некое постоянство значений, то вместо постоянного выбора MAX(alertID) я использую глобальную перемененную просчитываемую лишь раз, которую передаю в необходимую процедуру.
Пример рассматривает связку пользователя и типа сообщения.
Само сообщение генерируется и сохраняется совсем в другом месте. Моей задачей было сделать систему оповещений во внутреннем форуме системы администрации небольшого вап-портала. При генерации какого то определённого события, мне надо проверить нет ли для этого евента сообщения и подписан ли юзер на это уведомление. Сами уведомления и их текст к теме освящённой в посте отношения не имеют.
От ошибок ввода, конечно никто не застрахован, но я думаю глупо считать это ключевым моментом, так речь идёт о статичной таблице (tblAlerts не должна расти иначе флаги неуместны). Возможно, пример действительно не самый удачный, но уж очень не хотелось использовать избитый хороший пример — права доступа (R/W/X), набор которых собственно неизменен. А вот насчёт внешних ключей в constraint — если не check, то всегда есть trigger. Ну и естественно часть data integrity решается определением соответствующего enum с флагами в том же C#.
А что с внешними ключами (FK — как я понимаю)?
Как я и говорил — проблема будет при использовании визуальных редакторов.
Не получится просто перетянуть ключ из одной таблицы в другую на диаграмме и получить работающий constraint.
Ещё раз повторюсь, что флаги в чистом виде используют лишь в небольших проектах. Из личного опыта скажу, что как правило используют и обычный ключ со связью через дополнительную таблицу и флаг. Таким образом запросы не требующие быстрого ответа (например ежемесячная статистика) делают через флаг, так как работа с одной таблицей намного удобней чем работа с тремя, да и порой быстрее (зависит от сценариев). При этом есть возможность использовать стандартные пути (через связывающую таблицу) для операций JOIN и т.д…
Кстати дублирование данных часто используется для ускорения процессов. Допустим хранят имя (first name) и фамилию(last name) как по отдельности, так и вместе (full name), чтобы построить индекс и на этом общем (fullname) столбце, тем самым ускорив поиск, если подобные поиски неотъемлемая часть повседневной работы системы.
Флаги удобно использовать только при маленьком количестве опций, которые эти флаги отображают. Классический пример, конечно, это атрибуты файлов или права доступа. С таким маленьким количеством пермутаций индекс будет работать неплохо. И многие запросы можно оптимизировать добавив/заменив условия. Если нам надо получить пользователей отвечающих маске 6 (0110 — новости и на оповещения о личных сообщениях), то вместо битовой операции можно использовать:SELECT * FROM tblUsers WHERE (tblUsers.alert >= 6).
SELECT * FROM tblUsers WHERE (tblUsers.alert & 7) = 7
ведь можно заменить на:
SELECT * FROM tblUsers WHERE tblUsers.alert = 7.
В случае с OR (выбор подписчиков на флаг 2 или 4), то в запрос добавляется сравнение с минимумом SELECT * FROM tblUsers WHERE tblUsers.alert>=2 AND (tblUsers.alert & 6) > 0
Конечно же флаги — не выход для гигантских проектов. Как подсказывает опыт при больших объёмах и количестве запросов индексирование становиться, наверно, наиважнейшим (во всяком случае важнее нормализации данных).
А насчёт префикса — для наглядности. Когда-то меня учили добавлять префикс tbl таблицам и fld полям, но при переходе от университетской теории к работе, стало ясно, что подобные префиксы — дурная практика.
Найти можно здесь: www.kevinfreitas.net/extensions/
Для программистов: null!=true и null!=false
Это не правильный вывод, вводящий вас в последующие заблуждения.
Если аксиому не возможно доказать, то это совсем не значит, что она ложна. Дело в том, что логика бывает разной и использовать тут логику (NOT TRUE) EQUALS FALSE. Хоть и основа логики всегда одинакова TRUE NOT EQUALS FALSE. Правильным выводом об аксиоме будет (NOT TRUE) AND (NOT FALSE) = NOT (TRUE OR FALSE).
Пример ошибочности применения бинарной логики:
Утверждение: Не бывает рыжих слонов.
Не правильный вывод (сделанный подобно вашему): Все кто не рыжий — слон.
Правильный вывод: Если слон, то не рыжий.
Во всяком случае поиск по маске становиться сложней (допустим нам надо найти подписчиков на тип сообщений 2 и 3):
SELECT * FROM tblUsers WHERE alerts like '%3%' and alerts like '%2%'
А с флагами решение частично использовало бы преимущество индекса, не имело бы значение в каком порядке были добавлены подписки и сколько ещё подписок существует у пользователя:
SELECT * FROM tblUsers WHERE tblUsers.alert = 6 OR (tblUsers.alert & 6) > 0
или можно пойти на шаг дальше (в зависимости от cost-function):
SELECT * FROM (SELECT * FROM tblUsers WHERE tblUsers.alert>=6) as tblUsers1 WHERE (tblUsers1 .alert & 6) > 0
Из-за использования подзапроса результат (tblUsers1 ) не будет иметь индексов, но так как в битовой операции они нам всё равно не помогали, то сокращение количества этих самых битовых операции сыграет положительную роль.
Ещё на шаг дальше:
SELECT * FROM (SELECT * FROM tblUsers WHERE tblUsers.alert=6 or tblUsers.alert > (SELECT MAX(alertID) FROM tblAlerts)) as tblUsers1 WHERE tblUsers1 .alert = 6 OR (tblUsers1 .alert & 6) > 0
Так как таблица флагов (tblAlerts) подразумевает некое постоянство значений, то вместо постоянного выбора MAX(alertID) я использую глобальную перемененную просчитываемую лишь раз, которую передаю в необходимую процедуру.
Само сообщение генерируется и сохраняется совсем в другом месте. Моей задачей было сделать систему оповещений во внутреннем форуме системы администрации небольшого вап-портала. При генерации какого то определённого события, мне надо проверить нет ли для этого евента сообщения и подписан ли юзер на это уведомление. Сами уведомления и их текст к теме освящённой в посте отношения не имеют.
Как я и говорил — проблема будет при использовании визуальных редакторов.
Не получится просто перетянуть ключ из одной таблицы в другую на диаграмме и получить работающий constraint.
Ещё раз повторюсь, что флаги в чистом виде используют лишь в небольших проектах. Из личного опыта скажу, что как правило используют и обычный ключ со связью через дополнительную таблицу и флаг. Таким образом запросы не требующие быстрого ответа (например ежемесячная статистика) делают через флаг, так как работа с одной таблицей намного удобней чем работа с тремя, да и порой быстрее (зависит от сценариев). При этом есть возможность использовать стандартные пути (через связывающую таблицу) для операций JOIN и т.д…
Кстати дублирование данных часто используется для ускорения процессов. Допустим хранят имя (first name) и фамилию(last name) как по отдельности, так и вместе (full name), чтобы построить индекс и на этом общем (fullname) столбце, тем самым ускорив поиск, если подобные поиски неотъемлемая часть повседневной работы системы.
SELECT * FROM tblUsers WHERE (tblUsers.alert & 7) = 7
ведь можно заменить на:
SELECT * FROM tblUsers WHERE tblUsers.alert = 7.
В случае с OR (выбор подписчиков на флаг 2 или 4), то в запрос добавляется сравнение с минимумом SELECT * FROM tblUsers WHERE tblUsers.alert>=2 AND (tblUsers.alert & 6) > 0
Конечно же флаги — не выход для гигантских проектов. Как подсказывает опыт при больших объёмах и количестве запросов индексирование становиться, наверно, наиважнейшим (во всяком случае важнее нормализации данных).
А насчёт префикса — для наглядности. Когда-то меня учили добавлять префикс tbl таблицам и fld полям, но при переходе от университетской теории к работе, стало ясно, что подобные префиксы — дурная практика.