По вашему запросу ничего не найдено :(
Убедитесь, что запрос написан правильно, или посмотрите другие наши статьи:
img
SQL, произносится как "эс-кью-эль", является критическим инструментом для ученых в области данных. На самом деле, возможно, это самый важный язык для работы с данными. В этом руководстве для начинающих рассмотрим основы SQL. Начнем с ответа на простой вопрос: Что такое SQL? SQL (Structured Query Language) расшифровывается как язык структурированных запросов. Язык запросов - это своего рода язык программирования, предназначенный для облегчения получения конкретной информации из баз данных, именно это делает SQL. Проще говоря, SQL - это язык баз данных. Это важно, потому что большинство компаний хранят свои данные в базах данных. И хотя есть много типов баз данных (как MySQL, PostgreSQL, Microsoft SQL Server), большинство из них говорят на SQL, так что, взяв на вооружение основы SQL, вы сможете работать с любым из них. Даже если вы планируете выполнить анализ на другом языке, таком как Python, в большинстве компаний, скорее всего, потребуется использовать SQL для извлечения необходимых данных из базы данных компании. Согласно данным платформы Indeed на данный момент на только в США существует более 80 000 предложений по SQL. Давайте начнем с изучения SQL! В руководстве мы будем работать с набором данных сервиса обмена велосипедами Hubway, который включает в себя данные о более чем 1,5 миллионах поездок, совершенных через этот сервис. Мы начнем с того, что рассмотрим базы данных, каковы они и почему мы их используем, прежде чем начнем писать собственные запросы в SQL. Для изучения нам потребуется база, которую вы можете загрузить здесь: Скачать БД Основы SQL: реляционные базы данных Реляционная база данных - это база данных, которая хранит связанную информацию в нескольких таблицах и позволяет запрашивать информацию из нескольких таблиц одновременно. Легче понять, как это работает, продумав пример. Представьте, что у вас есть бизнес и вы хотите следить за информацией о продажах. В Excel можно настроить электронную таблицу со всей информацией, которую необходимо отслеживать, в виде отдельных столбцов: Номер заказа, дата, сумма к оплате, номер отслеживания отгрузки, имя, адрес и номер телефона клиента. Такое решение отлично подойдет для отслеживания информации, на начальных этапах работы, но, когда вы начнете получать повторные заказы от одного и того же клиента, вы обнаружите, что их имя, адрес и номер телефона хранятся в нескольких строках вашей электронной таблицы. По мере роста вашего бизнеса и увеличения количества отслеживаемых заказов эти избыточные данные займут ненужное место и, как правило, снизят эффективность вашей системы отслеживания продаж. Также могут возникнуть проблемы с целостностью данных. Например, нет гарантии, что для каждого поля будет установлен правильный тип данных или что имя и адрес будут каждый раз вводиться одинаково. При использовании реляционной базы данных, как и на приведенной выше схеме, можно избежать всех этих проблем. Можно настроить две таблицы: одну для заказов и одну для клиентов. Таблица "Клиенты" будет включать уникальный идентификационный номер для каждого клиента, а также имя, адрес и номер телефона, которые мы уже отслеживали. Таблица "Заказы" будет включать номер заказа, дату, сумму к оплате, номер отслеживания и вместо отдельного поля для каждой позиции данных клиента будет содержать столбец для идентификатора клиента. Это позволяет нам получить всю информацию о клиенте для любого заказа, но записи будут введены в базу только один раз, избегая при этом избыточных данных. С чем бы будем работать Начнем с открытия нашей базу данных. База данных имеет две таблицы, trips ( далее "поездки") и stations (далее "станции"). Давайте просто посмотрим на таблицу trips. Она содержит следующие столбцы: id - уникальное целое число, которое служит ссылкой на каждую поездку. duration - продолжительность поездки, измеренная в секундах; start_date - Дата и время начала поездки; start_station - целое число, соответствующее столбцу id в таблице stations для станции, на котором был арендован велосипед; end_date - Дата и время окончания поездки; end_station - Идентификатор станции, на которой завершилась поездка; bike_number - уникальный идентификатор Hubway для велосипеда, используемого в поездке; sub_type - тип подписки пользователя. "Зарегистрированный" для пользователей с членством, "Случайный" для пользователей без членства; zip_code - почтовый индекс пользователя (доступен только для зарегистрированных участников); birth_date - год рождения пользователя (доступен только для зарегистрированных участников); gender - пол пользователя (доступен только для зарегистрированных участников); Что мы анализируем Внизу перечислены вопросы, на которые мы должны ответить, используя информацию из БД и командами SQL, которые мы изучим чуть позже: Какова была продолжительность самого длительного путешествия? Сколько поездок совершили "зарегистрированные" пользователи? Какова средняя продолжительность поездки? Кто совершил более длительные поездки: зарегистрированные пользователи или гости? Какой велосипед использовался для большинства поездок? Какова средняя продолжительность поездок пользователей старше 30 лет? Команды SQL, которые мы будем использовать для ответа на эти вопросы: SELECT WHERE LIMIT ORDER BY GROUP BY AND OR MIN MAX AVG SUM COUNT Установка и настройка В данном руководстве мы будем использовать систему баз данных под названием SQLite3. SQLite стала частью Python начиная с версии 2.5, так что, если у вас установлен Python, почти наверняка уже в системе есть и SQLite. Python и библиотеку SQLite3 можно легко установить и настроить с помощью Anaconda, если они еще не установлены. Использование Python для запуска кода SQL позволяет импортировать результаты в датафрейм Pandas, что существенно облегчит отображение результатов в удобном для чтения формате. Это также означает, что мы сможем выполнить дальнейший анализ и визуализацию данных, которые мы получим из базы данных, хотя это будет выходить за рамки данного учебного пособия. Если же не хотите использовать или устанавливать Python, SQLite3 можно запустить из командной строки. Просто загрузите "предварительно скомпилированные двоичные файлы" с сайта SQLite3 и используйте следующую команду для открытия базы данных: ~$ sqlite hubway.db SQLite version 3.14.0 2016-07-26 15:17:14 Enter ".help" for usage hints.sqlite> Отсюда можно просто ввести запрос, который нужно выполнить, и увидеть возвращенные данные, в нашем окне терминала. Альтернативой использованию терминала является подключение к базе данных SQLite через Python. Это позволит нам использовать Jupyter для отображения результатов наших запросов в аккуратно отформатированной таблице. Для этого определим функцию, которая принимает наш запрос (сохраненный в виде строки) в качестве входных данных и показывает результат в виде форматированного датафрейма: import sqlite3 import pandas as pd db = sqlite3.connect('hubway.db') def run_query(query): return pd.read_sql_query(query,db) SELECT Первая команда, с которой мы будем работать - SELECT. SELECT будет основой почти каждого запроса, который мы напишем - он сообщает базе данных, какие столбцы мы хотим видеть. Можно указать столбцы по имени (разделенные запятыми) или использовать подстановочный знак * для возврата всех столбцов из таблицы. В дополнение к столбцам, которые мы хотим получить, мы также должны сообщить базе данных, из какой таблицы их получить. Для этого используется ключевое слово FROM, за которым следует имя таблицы. Например, если требуется просмотреть start_date и bike_number для каждой поездки в таблице trips, можно использовать следующий запрос: SELECT start_date, bike_number FROM trips; В этом примере мы начали с команды SELECT, чтобы база данных знала, что она должна найти некоторые данные. Затем мы сказали базе данных, что нас интересуют столбцы start_date и bike_number. Наконец, чтобы сообщить базе, что столбцы, которые мы хотим получить, являются частью таблицы trips мы использовали команду FROM. Важно знать, что при записи SQL-запросов необходимо заканчивать каждый запрос точкой с запятой (;). На самом деле не каждая база данных SQL требует этого, но такой стиль считается хорошим тоном создания запросов, поэтому лучше всего сформировать эту привычку. LIMIT Следующая команда, которую мы должны знать перед началом выполнения запросов к нашей базе данных Hubway, - LIMIT. LIMIT просто сообщает базе данных, сколько строк требуется вернуть. Запрос SELECT, который мы рассмотрели в предыдущем разделе, возвращает запрашиваемую информацию для каждой строки в таблице trips, но обычно это очень большое количество данных, в которых нет необходимости в данный момент. Если всех записей из БД нужно получить start_date и bike_number только для первых пяти поездок, к запросу следует добавить ключевое слово LIMIT следующим образом: SELECT start_date, bike_number FROM trips LIMIT 5; Мы просто добавили команду LIMIT, а затем число, представляющее количество строк, которые мы хотим вернуть. В данном примере мы использовали 5, но вы можете заменить их любым числом, чтобы получить соответствующий объем данных для проекта, над которым вы работаете. Мы будем много использовать LIMIT в наших запросах к базе данных Hubway в этом учебном пособии - таблица поездок содержит более 1,5 миллионов строк данных, и нам, конечно, не нужно отображать все. Давайте запустим наш первый запрос в базе данных Hubway. Сначала сохраним наш запрос в переменной типа "строка", а затем используем функцию, определенную ранее, чтобы отправить запрос к базе данных. Взгляните на следующий пример: query = 'SELECT * FROM trips LIMIT 5;' run_query(query) Этот запрос использует * в качестве подстановочного символа вместо указания возвращаемых столбцов. Это означает, что команда SELECT вернула нам каждый столбец из таблицы trips. Мы также использовали функцию LIMIT, чтобы ограничить вывод первыми пятью строками таблицы. Вы часто столкнетесь с ситуацией, когда программисты в своих запросах ключевые слова будут писать с заглавной буквы. Это негласное соглашение, которому мы будем следовать в этом учебном пособии, хотя это в основном вопрос предпочтения. Просто заглавная буква облегчает чтение кода, но на самом деле она никак не влияет на его функциональность. Если вы предпочитаете писать запросы строчными буквами, они будут выполняться правильно. В предыдущем примере были возвращены все столбцы из таблицы поездок. Если бы нас интересовали только длительность и дата начала, подстановочный символ можно было бы заменить на названия столбцов следующим образом: query = 'SELECT duration, start_date FROM trips LIMIT 5' run_query(query) ORDER BY Последняя команда, которую мы должны знать, прежде чем мы сможем ответить на первый из наших вопросов, - ORDER BY. Эта команда позволяет отсортировать базу данных по указанному столбцу. Чтобы использовать его, просто укажите имя столбца, по которому требуется выполнить сортировку. По умолчанию, ORDER BY сортирует результаты по возрастанию. Если требуется указать порядок сортировки базы данных, можно добавить ключевое слово ASC для сортировки по возрастанию или DESC - по убыванию. Например, если требуется отсортировать вывод из таблицы поездок от самой короткой по продолжительности до самой длинной, в запрос можно добавить следующую строку: ORDER BY duration ASC Вооружившись командами SELECT, LIMIT и ORDER BY мы теперь можем попытаться ответить на наш первый вопрос: какова была продолжительность самой длительной поездки? Чтобы ответить на этот вопрос, полезно разбить его на разделы и определить, какие команды нам потребуются для каждой части. Сначала нам нужно извлечь информацию из столбца duration таблицы поездок. Затем, чтобы найти, какая поездка самая длинная, мы можем отсортировать столбец длительности в порядке убывания. Итак, чтобы сформировать запрос, который получит нужную нам информацию, мы можем следовать следующей последовательности: Использовать SELECT для извлечения столбца duration FROM таблицы trips. Использовать ORDER BY для сортировки по столбцу duration и ключевое слово DESC для сортировки в порядке убывания. Использовать LIMIT, чтобы ограничить вывод 1 строкой Использование этих команд таким образом вернет одну строку с наибольшей длительностью, что даст нам ответ на наш вопрос. Еще одна деталь, которую следует отметить - по мере увеличения длины запроса, чтобы облегчить чтение кода, лучше разделять запрос на несколько строк. Это, как и в случае с заглавным шрифтом, вопрос личного предпочтения. Это не влияет на выполнение кода (система считывает код от начала до точки с запятой), но может сделать запросы более четкими и простыми для выполнения. В Python можно разделить строку на несколько строк, используя тройные кавычки. Давайте выполним запрос и выясним, сколько длилась самая длинная поездка. query = ''' SELECT duration FROM trips ORDER BY duration DESC LIMIT 1; ''' run_query(query) Теперь мы знаем, что самая длинная поездка длилась 9999 секунд, или чуть более 166 минут. С максимальным значением 9999, однако, мы не знаем, действительно ли это длина самого длинного рейса или база данных была настроена только для разрешения четырехзначного номера. Если это правда, то более длительные поездки сокращаются базой данных до четырех символов. В результате ожидаемо увидеть много поездок длительностью 9999 секунд. Чтобы убедиться, что все отрабатывает корректно, попробуем выполнить тот же запрос, что и раньше, но изменим LIMIT так, чтобы вернуть 10 наибольших по длительности поездок: query = ''' SELECT durationFROM trips ORDER BY duration DESC LIMIT 10 ''' run_query(query) Судя по выводу, в базе нет кучи поездок продолжительностью 9999, а это означает, что база ничего не отсекает. Но все еще трудно сказать, является ли это реальной длиной поездки или только максимально допустимое значение. Hubway взимает дополнительную комиссию за поездки длительностью более 30 минут (кто-то, продержавший велосипед в течение 9999 секунд, должен был бы заплатить дополнительные 25 долларов в виде комиссии), поэтому вполне вероятно, что разработчики решили обойтись 4-мя цифрами для отслеживания большинства поездок. WHERE Предыдущие команды отлично подходят для извлечения отсортированной информации для определенных столбцов, но что делать, если существует определенное подмножество данных, которые мы хотим просмотреть? Вот здесь на помощь приходит WHERE. Команда WHERE позволяет использовать логический оператор для указания строк, которые должны быть возвращены. Например, можно использовать следующую команду, чтобы вернуть каждую поездку, выполненную велосипедом с ID B00400: WHERE bike_number = "B00400" Наверное, уже заметили, что в этом запросе используем кавычки. Это потому, что bike_number хранится в виде строки. Если столбец содержит числовые типы данных, необходимость в кавычках отпадает. Давайте напишем запрос, который использует WHERE для возврата каждого столбца в таблице поездок для каждой строки длительностью больше 9990 секунд: query = ''' SELECT * FROM trips WHERE duration > 9990; ''' run_query(query) Как мы видим, этот запрос вернул 14 различных поездок, каждая продолжительностью 9990 секунд или более. Что-то, что выделяется в этом запросе, что все, кроме одного из результатов имеет sub_type "Случайный". Возможно, это свидетельствует о том, что "Зарегистрированные" пользователи больше осведомлены о дополнительных сборах за длительные поездки. Может быть, Хабуэй мог бы лучше передать свою политику ценообразования случайным пользователям, чтобы помочь им избежать чрезмерных расходов. Мы уже видим, что даже SQL запрос начального уровня может помочь нам ответить на бизнес-вопросы и найти информацию в наших данных. Возвращаясь к WHERE, мы также можем объединить несколько логических тестов в нашем предложении WHERE, используя AND или OR. Если, например, в нашем предыдущем запросе мы хотели получить только поездки длительностью более 9990 секунд, которые также имеют sub_type Registered, мы могли бы использовать оператор AND для указания обоих условий. Вот еще одна личная рекомендация: используйте круглые скобки, чтобы разделить каждый логический блок, как показано в коде ниже. Это не обязательно для работы кода, но круглые скобки упрощают понимание запросов по мере их усложнения. Давайте сейчас запустим этот запрос. Мы уже знаем, что это должно вернуть только один результат, так что должно быть легко проверить, что мы получили его правильно: query = ''' SELECT * FROM trips WHERE (duration >= 9990) AND (sub_type = "Registered") ORDER BY duration DESC; ''' run_query(query) Следующий вопрос, который мы изложили в начале статьи, - "Сколько поездок было совершено "зарегистрированными" пользователями?" Чтобы ответить на него, мы могли бы выполнить тот же запрос, что и выше, и изменить выражение WHERE, чтобы вернуть все строки, где sub_type равно "Registered", а затем подсчитать их. На самом деле SQL имеет встроенную команду COUNT для такого рода подсчетов, так что напрягать глаза нам не придется. COUNT позволяет выполнять вычисления в базе данных и избавить нас от проблем с написанием дополнительных сценариев для подсчета результатов. Чтобы использовать его, мы просто включаем COUNT (column_name) вместо (или в дополнение к) столбцов, которые мы хотим выбрать, как указано ниже: SELECT COUNT(id) FROM trips В данном случае не имеет значения, какой столбец мы выбираем для подсчета, потому что каждый столбец должен иметь данные для каждой строки в нашем запросе. Но иногда запрос может иметь отсутствующие (или "нулевые") значения для некоторых строк. Если мы не уверены, содержит ли столбец значения null, мы можем запустить COUNT для столбца id - столбец id никогда не имеет значение null, поэтому мы можем быть уверены, что наш счетчик не пропустит ничего. Мы также можем использовать COUNT (1) или COUNT (*) для подсчета каждой строки в нашем запросе. Стоит отметить, что иногда может потребоваться выполнение COUNT для столбца со значениями NULL. Например, может потребоваться узнать, сколько строк в нашей базе данных имеют пустые значения для указанного столбца. Давайте посмотрим на запрос, который позволит ответить на наш вопрос. Мы можем использовать SELECT COUNT (*) для подсчета общего количества возвращенных строк и WHERE sub_type = "Registered", чтобы убедиться, что мы подсчитываем только поездки, сделанные зарегистрированными пользователями. query = ''' SELECT COUNT(*)FROM trips WHERE sub_type = "Registered"; ''' run_query(query) Этот запрос сработал и вернул ответ на наш вопрос. Но заголовок столбца не особенно показателен. Если кто-то еще посмотрит на эту таблицу, он не сможет понять, что это значит. Если мы хотим сделать наши результаты более читаемыми, мы можем использовать ключевое слово AS, чтобы дать нашему выводу псевдоним. Давайте снова запустим предыдущий запрос, но дадим query = ''' SELECT COUNT(*) AS "Total Trips by Registered Users" FROM trips WHERE sub_type = "Registered"; ''' run_query(query) Функции агрегирования COUNT не единственный математический трюк, которым располагает SQL. Мы также можем использовать функции SUM, AVG, MIN и MAX для возврата суммы, среднего значения, минимума и максимума столбца соответственно. Эти функции наряду с COUNT называются функциями агрегирования. Итак, чтобы ответить на наш третий вопрос "Какова была средняя продолжительность поездки?", мы можем использовать функцию AVG для столбца duration (и, еще раз, использовать AS, чтобы дать нашему выходному столбцу более описательное имя): query = ''' SELECT AVG(duration) AS "Average Duration" FROM trips; ''' run_query(query) Получается, что средняя продолжительность поездки составляет 912 секунд, что составляет около 15 минут. Это имеет смысл, так как мы знаем, что Hubway взимает дополнительную плату за поездки в течение 30 минут. Сервис рассчитан на то, чтобы участники брали велосипеды на короткие дистанции, односторонние поездки. Как насчет нашего следующего вопроса, какие пользователи выполняют более длительные поездки? Мы уже знаем один способ ответить на этот вопрос - мы могли бы запустить два запроса SELECT AVG (duration) FROM trips добавив ключевое слово WHERE, которые ограничивают вывод для "зарегистрированных" и для "случайных" пользователей по отдельности. Но давайте сделаем это по-другому. SQL имеет в своем арсенале функцию и для ответа на этот вопрос в одном запросе с помощью команды GROUP BY. GROUP BY GROUP BY разделяет строки на группы на основе содержимого определенного столбца и позволяет выполнять агрегирующие функции для каждой группы. Чтобы лучше понять, как это работает, давайте посмотрим на столбец gender. Каждая строка может иметь одно из трех возможных значений в столбце пола "Мужской", "Женский" или "Нулевой" (отсутствует; у нас нет гендерных данных для случайных пользователей). Когда мы используем GROUP BY, база данных будет разделять каждую из строк на разные группы на основе значения в столбце пола, примерно так же, как мы можем разделить колоду карт по мастям. Это можно представить, как две группы, в одной все представители мужского пола, в другой - женского. Как только у нас будут две отдельные кучи, база данных будет выполнять любые агрегирующие функции в нашем запросе по каждой из них по очереди. Например, если бы мы использовали COUNT, запрос подсчитывал бы количество строк в каждой группе и возвращал бы значение для каждого по отдельности. Давайте посмотрим, как именно написать запрос, чтобы ответить на наш вопрос о том, кто совершает более длительные поездки: зарегистрированные пользователи или случайные. Как и в случае с каждым из наших запросов, мы начнем с SELECT, чтобы сообщить базе данных, какую информацию мы хотим получить. В этом случае нам нужны sub_type и AVG (duration). Мы также включим GROUP BY sub_type, чтобы разделить наши данные по типу подписки и вычислить средние значения зарегистрированных и случайных пользователей по отдельности. Вот как выглядит код, когда мы складываем все вместе: query = ''' SELECT sub_type, AVG(duration) AS "Average Duration" FROM trips GROUP BY sub_type; ''' run_query(query) Это большая разница! В среднем зарегистрированные пользователи совершают поездки продолжительностью около 11 минут, в то время как случайные пользователи тратят почти 25 минут на поездку. Зарегистрированные пользователи, вероятно, совершают более короткие и частые поездки, возможно, в рамках поездок на работу. Случайные пользователи, с другой стороны, тратят в два раза больше времени на поездку. Вполне возможно, что случайные пользователи, как правило, приезжие (например, туристы), которые более склонны совершать более длительные поездки, чтобы убедиться, что они обойдут и увидят все достопримечательности. Как только мы обнаружим эту разницу в данных, компания сможет исследовать ее, чтобы лучше понять, что данная разница вызвана Однако давайте продолжим. Наш следующий вопрос был: "Какой велосипед использовался для большинства поездок?" Мы можем ответить на это с помощью очень похожего запроса. Взгляните на следующий пример и посмотрите, можете ли вы выяснить, что делает каждая строка - мы пройдем ее шаг за шагом после этого, чтобы вы могли проверить, правильно ли вы получили: query = ''' SELECT bike_number as "Bike Number", COUNT(*) AS "Number of Trips" FROM trips GROUP BY bike_number ORDER BY COUNT(*) DESC LIMIT 1; ''' run_query(query) Как видно из выходных данных, велосипедные B00490 взяли больше всего поездок. Давайте рассмотрим, как получили данное значение: Первая строка - это предложение SELECT, указывающее базе данных, что мы хотим получить столбец bike_number и число всех строк в БД. В запросе также используется AS для указания базе данных отображать каждый столбец с более понятным названием. Во второй строке используем FROM, чтобы указать, что данные, которые мы ищем, находятся в таблице поездок. В третьей строке прибегли к хитрости. Тут используется команда GROUP BY, чтобы указать функции COUNT в первой строке подсчитать каждое значение для bike_number отдельно. В четвертой строке у нас есть функция ORDER BY, чтобы отсортировать таблицу в порядке убывания и убедиться, что наш наиболее используемый велосипед находится на самом верху. Наконец, мы используем LIMIT, чтобы ограничить вывод одной строкой, которая, как мы знаем, будет велосипедом, который использовался в наибольшем количестве поездок из-за того, как мы сортировали данные на четвертой строке. Арифметические операторы Наш последний вопрос немного сложнее других. Мы хотим знать среднюю продолжительность поездок зарегистрированных участников в возрасте старше 30 лет. Мы могли бы просто найти год, в котором родились 30-летние, а затем подставить это значение. Но есть более элегантным решение - использование арифметических операций непосредственно в нашем запросе. SQL позволяет использовать +, -, * и/для выполнения арифметической операции над всем столбцом одновременно. query = ''' SELECT AVG(duration) FROM trips WHERE (2017 - birth_date) > 30; ''' run_query(query) JOIN До сих пор мы рассматривали запросы, которые извлекают данные только из таблицы поездок. Однако одна из причин, по которой SQL настолько эффективен, заключается в том, что он позволяет извлекать данные из нескольких таблиц в одном запросе. Наша база данных по обмену велосипедами содержит вторую таблицу, станции. Таблица stations содержит информацию о каждом терминале в сети Hubway и включает столбец id, на который ссылается таблица trips. Прежде чем мы начнем работать с некоторыми реальными примерами из этой базы данных, давайте посмотрим на гипотетическую базу данных отслеживания заказов из более ранних. В этой базе данных были две таблицы, заказы и клиенты, и они были связаны столбцом customer_id. Допустим, мы хотели написать запрос, который вернул order_number и name для каждого заказа в базе данных. Если они оба были сохранены в одной таблице, можно было бы использовать следующий запрос: SELECT order_number, name FROM orders; К сожалению, столбец order_number и столбец name хранятся в двух разных таблицах, поэтому необходимо добавить несколько дополнительных команд. Давайте подумаем о дополнительных командах, которые должна знать база данных, прежде чем она сможет вернуть нужную информацию: В какой таблице находится столбец order_number? В какой таблице находится столбец name? Как информация в таблице заказов связана с информацией в таблице клиентов? Чтобы ответить на первые два из этих вопросов, мы можем включить имена таблиц для каждого столбца в нашу команду SELECT. Способ сделать это - просто написать имя таблицы и имя столбца, разделив их символом точки ".". Например, вместо SELECT order_number мы бы написали SELECT orders.order_number, customers.name. Добавление здесь имен таблиц помогает базе данных находить столбцы, которые мы ищем, указывая, в какой таблице искать каждый из них. Чтобы сообщить базе данных, как соединяются таблицы заказов и клиентов, мы используем JOIN и ON. JOIN указывает, какие таблицы должны быть соединены, а ON указывает, какие столбцы в каждой таблице связаны. Мы будем использовать внутреннее соединение, что означает, что команда вернет только те строки, где столбцы, указанные в ON, совпадают. В этом примере мы хотим использовать JOIN для любой таблицы, которую мы не включили в команду FROM. Таким образом, мы можем либо использовать FROM orders INNER JOIN customers, либо FROM customers INNER JOIN orders. Как мы уже обсуждали ранее, эти таблицы связаны между собой столбцом customer_id в каждой таблице. Поэтому используем ON, чтобы сообщить базе данных, что эти два столбца ссылаются на одно и то же: ON orders.customer_ID = customers.customer_id Еще раз используем "." чтобы база данных знала, в какой таблице находится каждый из этих столбцов. Итак, когда мы сложим все это вместе, мы получим запрос, который выглядит следующим образом: SELECT orders.order_number, customers.name FROM orders INNER JOIN customers ON orders.customer_id = customers.customer_id Этот запрос вернет номер каждого заказа в базе данных наряду с именем клиента, который сделал данные заказ. Возвращаясь к нашей базе данных Hubway, мы теперь можем написать несколько запросов, чтобы увидеть JOIN в действии. Прежде чем начать, мы должны взглянуть на остальные столбцы в таблице станций. Вот запрос, чтобы показать нам первые 5 строк, чтобы мы могли увидеть, как выглядит таблица станций: query = ''' SELECT * FROM stations LIMIT 5; ''' run_query(query) id - уникальный идентификатор для каждой станции (соответствует столбцам start_station и end_station в таблице поездок); station - название станции; municipality - муниципалитет, в котором находится станция (Бостон, Бруклин, Кембридж или Сомервилл); lat - Широта станции; lng - долгота станции; А вот вопросы, на которые мы должны ответить, исследовав данные из базы: Какие станции чаще всего используются для поездок в оба конца? Сколько поездок начинается и заканчивается в разных муниципалитетах? Как и прежде, мы попытаемся ответить на некоторые вопросы основываясь на данных, первый вопрос: "Какая станция является наиболее частой отправной точкой?" Давайте шаг за шагом сформируем запрос для ответа на этот вопрос: Сначала мы используем SELECT для возврата столбца station из таблицы станций и COUNT для получения числа строк. Далее мы указываем таблицы, которые мы хотим объединить JOIN, и указываем базе данных соединить их столбцом ON start_station из таблицы поездок и столбцом id в таблице станций. Затем переходим к основной части нашего запроса - мы группируем по столбцу станция таблицы станций (GROUP BY station), чтобы наш COUNT подсчитал количество поездок для каждой станции отдельно Наконец, мы можем отсортировать по нашим COUNT ORDER BY COUNT LIMIT и ограничить вывод для управления количеством результатов. query = ''' SELECT stations.station AS "Station", COUNT(*) AS "Count" FROM trips INNER JOIN stations ON trips.start_station = stations.id GROUP BY stations.station ORDER BY COUNT(*) DESC LIMIT 5; ''' run_query(query) Если вы знакомы с Бостоном, вы поймете, почему это самые популярные станции. Южный вокзал является одной из главных пригородных железнодорожных станций в городе, Чарльз-стрит проходит вдоль реки недалеко от некоторых красивых живописных маршрутов, а улицы Бойлстон и Бикон находятся прямо в центре вблизи офисных зданий. Следующий вопрос, который мы рассмотрим, - какие станции чаще всего используются для поездок туда и обратно? Мы можем использовать тот же запрос, что и раньше. Мы будем выбирать те же выходные столбцы и присоединять таблицы таким же образом, но на этот раз мы добавим условие WHERE, чтобы ограничить наш COUNT поездками, где start_station совпадает с end_station. query = ''' SELECT stations.station AS "Station", COUNT(*) AS "Count" FROM trips INNER JOIN stations ON trips.start_station = stations.id WHERE trips.start_station = trips.end_station GROUP BY stations.station ORDER BY COUNT(*) DESC LIMIT 5; ''' run_query(query) Как мы видим, ряд станций из этого списка аналогичен предыдущему списку, но их количество значительно ниже. Самые загруженные станции те же самые, но более низкие цифры в целом дают возможность предполагать, что люди обычно используют велосипеды Hubway, чтобы добраться от точки A до точки B, а не ездить на велосипеде некоторое время, прежде чем вернуться туда, где они начали. Здесь есть одно существенное отличие - Эспланд, который не был одной из самых загруженных станций по результатам нашего первого запроса, кажется самым загруженным для поездок туда и обратно. Почему? Что ж, картина стоит тысячи слов. Это, безусловно, выглядит как хорошее место для велопробега: На следующий вопрос: сколько поездок начинается и заканчивается в разных муниципалитетах? Этот вопрос делает заставляет нас двигаться дальше. Мы хотим знать, сколько поездок начинается и заканчивается в другом муниципалитете. Чтобы достичь этого, нам нужно присоединить таблицу поездок к таблице станций дважды. Один раз по столбцу start_station, а затем по столбцу end_station. Для этого необходимо создать псевдоним для таблицы станций, чтобы можно было различать данные, относящиеся к start_station, и данные, относящиеся к end_station. Мы можем сделать это точно так же, как присваивали псевдонимы отдельным столбцам, чтобы они отображались с более интуитивным именем, используя AS. Например, чтобы присоединить таблицу станций к таблице поездок с помощью псевдонима "start", можно использовать следующий код. Затем мы можем объединить "start" с именами столбцов с помощью "." для ссылки на данные, полученные из этого конкретного JOIN (вместо второго JOIN, где мы объединим таблицы по end_station столбец): INNER JOIN stations AS start ON trips.start_station = start.id Вот как будет выглядеть последний запрос при его выполнении. Обратите внимание, что мы использовали " " для представления "не равно", но != также будет работать. query = ''' SELECT COUNT(trips.id) AS "Count" FROM trips INNER JOIN stations AS start ON trips.start_station = start.id INNER JOIN stations AS end ON trips.end_station = end.id WHERE start.municipality end.municipality; ''' run_query(query) Это показывает, что около 300 000 из 1,5 миллионов поездок (или 20%) закончились в другом муниципалитете, - еще одно доказательство того, что люди в основном используют велосипеды Hubway для относительно коротких путешествий, а не более длительных поездок между городами. Если вы зашли так далеко, поздравляю! Вы начали осваивать основы SQL. Мы рассмотрели ряд важных команд, а также агрегирующие и арифметические функции. Они дадут вам прочную основу для развития по мере того, как вы продолжите свой путь в изучении SQL. Что дальше? После завершения данного руководства по SQL можно будет выбрать базу данных, которую вы найдете интересной, и написать запросы для извлечения информации из неё. Хорошим первым шагом может быть продолжение работы с базой данных Hubway, чтобы узнать, чего еще интересного можно достать из этой базы. Вот несколько вопросов, на которые вы можете попытаться ответить: Сколько поездок понесли дополнительные сборы (длились дольше 30 минут)? Какой велосипед использовался дольше всего? Какие пользователи, зарегистрированные или случайные, совершали больше поездок в оба конца? Какой муниципалитет имеет наибольшую среднюю продолжительность?
img
В первой статье серии EIGRP мы познакомились с функциями EIGRP, рассмотрели пример базовой конфигурации и набор команд проверки. Сегодня, в этой статье, мы углубимся в понимание того, как EIGRP устанавливает соседство, изучает маршрут к сети, определяет оптимальный маршрут к этой сети, и пытается ввести этот маршрут в таблицу IP-маршрутизации маршрутизатора. Предыдущие статьи из цикла про EIGRP: Часть 1. Понимание EIGRP: обзор, базовая конфигурация и проверка Следующие статьи из цикла: Часть 2.2. Установка K-значений в EIGRP Часть 3. Конвергенция EIGRP – настройка таймеров Часть 4. Пассивные интерфейсы в EIGRP Часть 5. Настройка статического соседства в EIGRP Часть 6. EIGRP: идентификатор роутера и требования к соседству Операции EIGRP могут быть концептуально упрощены в три основных этапа: Этап 1. Обнаружение соседей: посредством обмена приветственными сообщениями EIGRP-спикер маршрутизаторы обнаруживают друг друга, сравнивают параметры (например, номера автономной системы, K-значения и сетевые адреса) и определяют, должны ли они образовывать соседство. Этап 2. Обмен топологиями: если соседние EIGRP маршрутизаторы решают сформировать соседство, они обмениваются своими полными таблицами топологии друг с другом. Однако после установления соседства между маршрутизаторами передаются только изменения существующей топологии. Этот подход делает EIGRP намного более эффективным, чем протокол маршрутизации, такой как RIP, который объявляет весь свой список известных сетей через определенные интервалы времени. Этап 3. Выбор маршрутов: как только таблица топологии EIGRP маршрутизатора заполнена, процесс EIGRP проверяет все изученные сетевые маршруты и выбирает лучший маршрут к каждой сети. EIGRP считает, что сетевой маршрут с самой низкой метрикой является лучшим маршрутом к этой сети. Очень важно, что в когда вы читаете вышеописанные этапы, подробно описывающее обнаружение соседей EIGRP, обмен топологией и выбор маршрута, должны понимать, что в EIGRP, в отличие от OSPF, нет понятия назначенного маршрутизатора (DR) или резервного назначенного маршрутизатора (BDR). Обнаружение соседей и обмен топологиями Чтобы лучше понять, как маршрутизатор EIGRP обнаруживает своих соседей и обменивается информацией о топологии с этими соседями, рассмотрим рисунок ниже. Шесть шагов, изображенных на рисунке выше, выполняются следующим образом: Шаг 1. Маршрутизатор OFF1 хочет видеть, есть ли какие-либо EIGRP-спикер маршрутизаторы вне его интерфейса Gig 0/1, с которым он мог бы, возможно, сформировать соседство. Таким образом, он осуществляет многоадресную рассылку приветственного сообщения EIGRP (EIGRP Hello) на хорошо известный EIGRP multicast-адрес 224.0.0.10 с просьбой к любым EIGRP-спикер маршрутизаторам, идентифицировать себя. Шаг 2. После получения приветственного сообщения маршрутизатора OFF1 маршрутизатор OFF2 отправляет одноадресное сообщение обновления (unicast Update message)обратно на IP-адрес маршрутизатора OFF1 10.1.1.1. Это сообщение обновления содержит полную таблицу топологии EIGRP маршрутизатора OFF2. Шаг 3. Маршрутизатор OFF1 получает обновление маршрутизатора OFF2 и отвечает одноадресным сообщением подтверждения (Acknowledgement (ACK), отправленным на IP-адрес маршрутизатора OFF2 10.1.1.2. Шаг 4. Затем процесс повторяется, и роли меняются местами. В частности, маршрутизатор OFF2 отправляет приветственное сообщение на адрес многоадресной рассылки EIGRP 224.0.0.10. Шаг 5. Маршрутизатор OFF1 отвечает на приветственное сообщение маршрутизатора OFF2 одноадресным обновлением (unicast Update), содержащим полную таблицу топологии EIGRP маршрутизатора OFF1. Это unicast Update достигается IP-адрес маршрутизатора OFF2 10.1.1.2. Шаг 6. Маршрутизатор OFF2 получает информацию о маршрутизации маршрутизатора OFF1 и отвечает одноадресным сообщением ACK, отправленным на IP-адрес маршрутизатора OFF1 10.1.1.1. На этом этапе было установлено соседство EIGRP между маршрутизаторами OFF1 и OFF2. Маршрутизаторы будут периодически обмениваться приветственными сообщениями, чтобы подтвердить, что сосед каждого маршрутизатора все еще присутствует. Однако это последний раз, когда маршрутизаторы обмениваются своей полной информацией о маршрутизации. Последующие изменения топологии объявляются через частичные обновления, а не полные обновления, используемые во время создания соседства. Кроме того, обратите внимание, что сообщения обновления во время установления соседа были отправлены как одноадресные сообщения. Однако будущие сообщения обновления отправляются как многоадресные сообщения, предназначенные для 224.0.0.10. Это гарантирует, что все EIGRP-спикер маршрутизаторы на сегменте получают сообщения об обновлении. EIGRP имеет преимущество перед OSPF в том, как он отправляет свои сообщения об обновлении. В частности, сообщения об обновлении EIGRP отправляются с использованием надежного транспортного протокола ( Reliable Transport Protocol (RTP). Это означает, что, в отличие от OSPF, если сообщение обновления будет потеряно при передаче, он будет повторно отправлено. Примечание: аббревиатура RTP также относится к Real-time Transport Protocol (RTP), который используется для передачи голосовых и видеопакетов. Выбор маршрута Маршруты, показанные в таблице топологии EIGRP, содержат метрическую информацию, указывающую, насколько "далеко" она находится от конкретной целевой сети. Но как именно рассчитывается эта метрика? Расчет метрики EIGRP немного сложнее, чем с RIP или OSPF. В частности, метрика EIGRP по умолчанию является целочисленным значением, основанным на пропускной способности и задержке. Также, вычисление метрики может включать и другие компоненты. Рассмотрим формулу вычисления метрики EIGRP: Обратите внимание, что расчет метрики включает в себя набор K-значений, которые являются константами, принимающие нулевые значения или некоторые положительные целые числа. Расчет также учитывает пропускную способность, задержку, нагрузку и надежность (bandwidth, delay, load, reliability). Интересно, что большая часть литературы по EIGRP утверждает, что метрика также основана на Maximum Transmission Unit (MTU). Однако, как видно из формулы расчета метрики, MTU отсутствует. Так в чем же дело? Учитывает ли EIGRP MTU интерфейса или нет? В самом начале разработки EIGRP, MTU был обозначен как Тай-брейкер, если два маршрута имели одинаковую метрику, но разные значения MTU. В такой ситуации был бы выбран маршрут с более высоким MTU. Таким образом, хотя сообщение об обновлении EIGRP действительно содержит информацию MTU, эта информация непосредственно не используется в расчетах метрик. Далее, давайте рассмотрим каждый компонент расчета метрики EIGRP и tiebreaking MTU: Bandwidth (Пропускная способность): значение пропускной способности, используемое в расчете метрики EIGRP, определяется путем деления 10 000 000 на пропускную способность (в Кбит / с) самого медленного канала вдоль пути к целевой сети. Delay (Задержка): в отличие от полосы пропускания, которая представляет собой "самое слабое звено", значение задержки является кумулятивным. В частности, это сумма всех задержек, связанных со всеми интерфейсами, которые используются чтобы добраться до целевой сети. Выходные данные команды show interfaces показывают задержку интерфейса в микросекундах. Однако значение, используемое в расчете метрики EIGRP, выражается в десятках микросекунд. Это означает, что вы суммируете все задержки выходного интерфейса, как показано в выводе show interfaces для каждого выходного интерфейса, а затем делите на 10, чтобы получить единицу измерения в десятки микросекунд. Reliability (Надежность): надежность-это значение, используемое в числителе дроби, с 255 в качестве ее знаменателя. Значение дроби указывает на надежность связи. Например, значение надежности 255 указывает на то, что связь надежна на 100 процентов (то есть 255/255 = 1 = 100 процентов). Load (Нагрузка): как и надежность, нагрузка-это значение, используемое в числителе дроби, с 255 в качестве ее знаменателя. Значение дроби указывает, насколько занята линия. Например, значение нагрузки 1 указывает на то, что линия загружена минимально (то есть 1/255 = 0,004 1%) MTU: хотя он не отображается в Формуле вычисления метрики EIGRP, значение MTU интерфейса (которое по умолчанию составляет 1500 байт) переносится в сообщение обновления EIGRP, которое будет использоваться в случае привязки (например, два маршрута к целевой сети имеют одну и ту же метрику, но разные значения MTU), где предпочтительно более высокое значение MTU. Для улучшения запоминания используйте следующий алгоритм Big Dogs Really Like Me. Где B в слове Big ассоциируется с первой буквой в слове Bandwidth. Буква D в слове Dogs соответствует первой букве D в слове Delay, и так далее. Однако по умолчанию EIGRP имеет большинство своих K-значений равными нулю, что значительно упрощает расчет метрики, учитывая только пропускную способность и задержку. В частности, значения K по умолчанию являются: K1 = 1 K2 = 0 K3 = 1 K4 = 0 K5 = 0 Если мы подставим эти дефолтные значения K в расчет метрики EIGRP, то значение каждой дроби будет равно нулю, что сводит формулу к следующему: Чтобы закрепить знания по вычислению метрики, давайте проведем расчет метрики и посмотрим, соответствует ли она нашей таблице топологии EIGRP. Рассмотрим топологию, показанную на рисунке ниже. Предположим, что мы хотим вычислить метрику для сети 198.51.100.0/24 от роутера OFF1 для маршрута, который идет от OFF1 до OFF2, а затем выходит в целевую сеть. Из топологии мы можем определить, что нам нужно будет выйти с двух интерфейсов маршрутизатора, чтобы добраться от маршрутизатора OFF1 до сети 198.51.100.0 /24 через маршрутизатор OFF2. Эти два выходных интерфейса являются интерфейсами Gig0/1 на маршрутизаторе OFF1 и интерфейсом Gig0/3 на маршрутизаторе OFF2. Мы можем определить пропускную способность и задержку, связанные с каждым интерфейсом, изучив выходные данные команд show interfaces, приведенных в следующем примере. Определение значений пропускной способности и задержки интерфейса на маршрутизаторах OFF1 и OFF2 Из приведенного выше примера мы видим, что оба выходных интерфейса имеют пропускную способность 1 000 000 Кбит/с (то есть 1 Гбит/с). Кроме того, мы видим, что каждый выходной интерфейс имеет задержку в 10 микросекунд. Значение пропускной способности, которое мы вводим в нашу формулу вычисления метрики EIGRP, - это пропускная способность самого медленного канала на пути к целевой сети, измеряемая в Кбит/с. В нашем случае оба выходных интерфейса имеют одинаковую скорость соединения, то есть мы говорим, что наша "самая медленная" связь составляет 1 000 000 Кбит/с. Для примера ниже показаны общие значения по умолчанию для пропускной способности и задержки на различных типах интерфейсов маршрутизатора Cisco. Общие значения по умолчанию для пропускной способности и задержки интерфейса: Наше значение задержки может быть вычислено путем сложения задержек выходного интерфейса (измеренных в микросекундах) и деления на 10 (чтобы дать нам значение, измеренное в десятках микросекунд). Каждый из наших двух выходных интерфейсов имеет задержку в 10 микросекунд, что дает нам суммарную задержку в 20 микросекунд. Однако мы хотим, чтобы наша единица измерения была в десятках микросекунд. Поэтому мы делим 20 микросекунд на 10, что дает нам 2 десятка микросекунд. Теперь у нас есть два необходимых значения для нашей формулы: пропускная способность = 1 000 000 Кбит/с и задержка = 2 десятка микросекунд. Теперь давайте добавим эти значения в нашу формулу: Вычисленное значение показателя EIGRP составляет 3072. Теперь давайте посмотрим, является ли это фактической метрикой, появляющейся в таблице топологии EIGRP маршрутизатора OFF1. Выходные данные команды show ip eigrp topology, выведенные на маршрутизаторе OFF1, показаны в следующем примере. Проверка метрики EIGRP для сети 198.51.100.0/24 на маршрутизаторе OFF1 Как и предполагалось, метрика (также известная как допустимое расстояние) от маршрутизатора OFF1 до Сети 198.51.100.0 /24 через маршрутизатор OFF2 составляет 3072. Напомним, что в этом примере мы использовали значения K по умолчанию, что также является обычной практикой в реальном мире. Однако для целей проектирования мы можем манипулировать K-значениями. Например, если мы обеспокоены надежностью каналом связи или нагрузкой, которую мы могли бы испытать на линии, мы можем манипулировать нашими K-значениями таким образом, чтобы EIGRP начал бы рассматривать надежность и/или нагрузку в своем метрическом расчете. В следующей статье мы рассмотрим, как мы можем изменить эти K - значения в EIGRP по умолчанию.
img
В статье пойдет речь о расположении файлов и папок, как использовать поиск для нахождения нужной информации. Задача ознакомление с предназначение основных папок в операционной системе Linux и то, что в них находиться. Разберемся в структуре FHS и посмотрим, как искать файлы и команды. FHS (File System Hierarchy Standard) – это стандартная иерархия ОС. Согласно Hierarchy FHS - есть стандартные папки, которые должны располагаться в корне. Вот классическое расположение файлов и папок в корневой папке ОС Linux. Стандарт FHS был изначально предназначен для того, чтобы во всех дистрибутивах ОС Linux могли понять и найти все, что нам нужно. Некоторые дистрибутивы Linux отклоняются от этого стандарта, но не сильно в целом данный стандарт соблюдается. Перечислим основные папки и их предназначение. /bin – базовые исполняемые файлы /boot – файлы loader /dev – устройства /etc – конфигурация ПК /home – домашние директории /lib – библиотеки ядра /proc – информация о работающей системе /media – монтирование носителей /mnt – монтирование носителей /opt – дополнительное программное обеспечение /root – домашняя директория админа /sbin – основные программы настройки системы /srv – данные системных служб /tmp – временные файлы /usr – бинарные файлы пользователей /var - переменные Первая папка bin в ней находятся базовые исполняемые файлы команд, т.е все команды которые может использовать пользователь они находятся здесь в данной папке. Папка boot – в данной папке находятся файлы загрузчика. Обычно это отдельный диск примонтированный в котором находиться ядро Linux. В папке dev – находятся файлы всех устройств в операционной системе Linux все и даже устройства представляют собой файлы. Папка etc – здесь находиться конфигурация нашего конкретного ПК, в ней много подпапок и в ней лежит конфигурация. В директории home находятся домашние папки всех пользователей, кроме пользователя root. В данной папке находятся документы, рабочий стол и т.д все что относится к пользователю. Папка lib здесь находятся общие библиотеки и модули ядра. Папка proc – здесь находятся вся информация о запущенных в данный момент процессах. В данную папку монтируется виртуальная файловая система procfs. Папка media создана для монтирования съемных накопителей типа USB или CD-ROM. В старых версиях Linux и до сих пор осталась, есть папка mnt. Раньше в нее монтировались съемные носители, теперь же данную папку обычно используют для монтирования дополнительных файловых систем. Папка opt - для установки дополнительного программного обеспечения. Папка root – говорит сама за себя. Папка sbin в данной папке лежат настройки серьезных таких компонент, как файрвол iptables, например, или процесс инициализации init. Папка srv в ней лежат данные для всех системных служб. Папка tmp – понятно, что в ней хранятся временные файлы. Причем данные файлы там хранятся до перезагрузки операционной системы, во время нее они удаляются. В папке usr хранятся двоичные файлы, которые относятся непосредственно к пользователю, например, игры или программы, т.е то что пользователь самостоятельно установил. Папка var – папка переменные, здесь обычно размещается почта или логи программ. Понятно, что это стандарт во многих дистрибутивах могут быть отклонения, но в том или ином виде все эти папки присутствуют в различных дистрибутивах. Подробнее про структуру FHS можно прочитать здесь Вторая часть не менее важная, как же найти в данных папках необходимую информацию. Команды, используемые для поиска: Grep – Утилита поиска по содержимому в том числе и внутри файла Find - Утилита поиска файлов по свойствам. Серьезная утилита, которая начинает поиск файлов по файловой системе в реальном времени, у данной утилиты есть множество ключей и параметров Locate – Это быстрый поиск файлов. Which – Поиск команды. Выводит минимальное количество информации Type – Вывод точной команды Whereis – Поиск команды, исходников и мануалов. Серьезный глубокий инструмент Начнем с find / -name mail. Данная команда начнет искать в корневой папке / все файлы с именем mail. Данная команда рекурсивно осуществляет поиск по всей файловой системе. Т.к мы запустили поиск от пользователя root, то он пробежался по всем папкам спокойно, если запускать от обычного пользователя, то может не хватать прав. Есть другая команда - locate mail. Данная команда отрабатывает практически мгновенно. Команда find искала именно по синтаксису, плюс можно добавлять сложные конструкции поиска. Команда locate делает проще показывает все где находится сочетание символов. Запустим поиск с помощью команды find / -user siadmin, поиск будет искать все что касается данного пользователя. Поиск опять идет дольше, чем поиск командой locate siadmin. Дело в том, что данная команда по умолчанию ищет не везде и у нее есть конфигурационный файл cat /etc/updatedb.conf. В данном конфигурационном файле мы можем увидеть, что данная утилита не ищет в примонтированных файловых системах. Даная строчка # PRUNENAMES=".git .bzr .hg .svn", говорит о том , что в данных форматы в поиске не выдаются. Поиск не производится в папках PRUNEPATHS="/tmp /var/spool /media /var/lib/os-prober /var/lib/ceph /home/.ecryptfs /var/lib/schroot". И не ищет в перечисленных файловых системах в файле. Данный файл можно конфигурировать и будут манятся параметры поиска. Создадим файл текстовый touch Vadim.txt. И попробуем найти - locate Vadim.txt. Ничего не нашел. find Vadim.txt - поиск успешен. locate работает с индексной локацией. Данный механизм напоминает индексацию файлов в MS Windows. Проходит индексация файлов и папок и после этого windows знает, что и где лежит. А если индексация не была проведена, то операционная система Windows или говорит, что ничего не найдено или поиск происходит длительное время. Аналогично утилита locate работает в Linux. Раз в день, команда locate запускает команду find. Команда find пробегает по всей файловой системе, а команда locate создает некую Базу данных и запоминает где и что находиться. Именно поэтому команда find работает долго, а команда locate работает практически моментально. Locate знает, где и что лежит в тот момент когда find искал. Но есть большой минус, данная функция происходит раз в день и изменения могут быть не актуальны. Для обновления базы данных команды locate, необходимо ее запустить вручную updatedb. Т.е ест конфигурация /etc/updatedb.conf и мы запускаем обновление Базы данных команды. После обновления, команда будет практически мгновенно находить. И последняя часть статьи, в которой необходимо рассмотреть поиск по командам. Тут достаточно просто, есть команда ls – она показывает содержимое папки. Мы можем найти где находиться данная команда which ls и получим, что она находиться /bin/ls. Т.е. команда ls хранится в папке bin – где хранятся бинарники тех команд, которые могут быть вызваны пользователями. По сути когда мы набираем команду ls, мы вводим /bin/ls. У нас есть команда type. Обратите внимание, когда мы вызываем команду ls срабатывает подсветка файлов и так далее, т.е. настройки оболочки. Когда мы запускаем напрямую /bin/ls то вызывается непосредственно команда и игнорируются настройки оболочки. Причина заключается в том, что когда мы запускаем просто команду ls, то она запускается с некоторыми ключами. Чтобы узнать, что за ключи используются необходимо набрать type ls. Обратите внимание, что команда ls – это алиаспсевдоним. Т.е запуская в таком режиме, фактически мы вводим /bin/ls –color=auto. И получаем красивый вывод. Type позволяет выводить псевдоним. Есть еще одна команда, которая более детальную информацию выводит whereis ls. Для ls там не много информации. Показывает, где лежит и к какому пакету относится.
ВЕСЕННИЕ СКИДКИ
40%
50%
60%
До конца акции: 30 дней 24 : 59 : 59