{"id":32445890,"url":"https://github.com/bar1o/it-asset-management","last_synced_at":"2026-05-15T18:32:50.510Z","repository":{"id":297285105,"uuid":"996311760","full_name":"Bar1o/it-asset-management","owner":"Bar1o","description":"HSE Course Project on Modeling and Creating DB (Data Modeling, Data Analysis for companies)","archived":false,"fork":false,"pushed_at":"2025-06-04T19:50:45.000Z","size":3272,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-06-04T23:54:50.775Z","etag":null,"topics":["analytics","bisiness","db","erd","sql"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Bar1o.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-04T19:08:46.000Z","updated_at":"2025-06-04T19:50:47.000Z","dependencies_parsed_at":"2025-06-05T00:06:20.089Z","dependency_job_id":null,"html_url":"https://github.com/Bar1o/it-asset-management","commit_stats":null,"previous_names":["bar1o/it-asset-management"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Bar1o/it-asset-management","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Bar1o%2Fit-asset-management","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Bar1o%2Fit-asset-management/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Bar1o%2Fit-asset-management/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Bar1o%2Fit-asset-management/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Bar1o","download_url":"https://codeload.github.com/Bar1o/it-asset-management/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Bar1o%2Fit-asset-management/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":281055225,"owners_count":26436350,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-26T02:00:06.575Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["analytics","bisiness","db","erd","sql"],"created_at":"2025-10-26T04:01:35.549Z","updated_at":"2025-10-26T04:02:57.203Z","avatar_url":"https://github.com/Bar1o.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"---\nmarp: true\ntheme: custom\npaginate: true\n_paginate: false\nfooter: 'IT Asset Management'\n\n---\n\n\u003c!-- _class: title-box logo2 --\u003e\n\n![alt text](pics/logo2.svg)\n\n\n# IT Asset Management\n\n\u003cbr\u003e\n\nНИУ ВШЭ\nг. Москва, 2025\n\n---\n\n\u003c!-- class: box --\u003e\n\n\n## Цель проекта\n\nПроект посвящен проектированию и разработке базы данных для системы управления оборудованием (устройство, ноутбуки, периферия) в компании.\n\nМоделирование БД осуществлялось с помощью ERD в нотации Чен (Chen-notaion). Взаимосвязи между таблицами указаны в другой ERD.\n\n**Ключевые слова:** Моделирование, ERD, Архитектура, Аналитика, SQL, Запросы, База данных\n\nСм. презентацию [DB-project](DB-project.pdf) для более подробного ознакопления в удобном формате. \n\n---\n\n## Project goal\n\nThe project is devoted to the design and development of a database for the system of equipment management (device, laptops, peripherals) in the company.\n\nThe database was modeled using ERD in Chen-notation. The relationships between the tables are specified in another ERD.\n\n**Keywords:** Modeling, ERD, Architecture, Analytics, SQL, Queries, Database\n\nCheck out the [DB-project](DB-project.pdf) presentation for more details in a convenient format. \n\n\n---\n\n## Инициализация проекта для локального запуска\n\nСоздание БД:\n```py\npython3 -m db.py\n```\nПосле этого создастся файл `local.db`. БД создается с помощью `makedb.sql`.\n\nЕсли Вы используете VS Code, то установите расширение SQLite для совершения запросов к БД.\n\nЗапросы, упомянутые здесь и в презентации, есть в файле `queries.sql`: **15+** запросов, где есть агрегирующие функции, подзапросы, CTE, VIEW, триггеры, оконные функции.\n\nЗапросы пишутся в файл `queries.sql`.\n\n\n---\n\u003c!-- class: box --\u003e\n\n## Описание БД\n**Назначение:** учёт IT-оборудования, сотрудников, отделов, поставщиков, управлениу назначениями оборудования и его обслуживанием (ремонтом).\n\n**Основные цели:**\n-\tЦентрализованный учёт IT-активов по отделам и сотрудникам.\n-\tПрослеживание историй назначений и обслуживания оборудования.\n-\tАнализ распределения активов по местоположениям и поставщикам.\n-\tКонтроль за состоянием активов (новое, на ремонте и пр.).\n\n**СУБД:** SQLite 3.47.2\n\n---\n\n\n## DB description\n**Purpose:** Accounting of IT equipment, employees, departments, suppliers, management of equipment assignments and its maintenance (repair).\n\n**Main purposes:**\n- Centralized accounting of IT assets by departments and employees.\n- Tracking of equipment assignment and maintenance histories.\n- Analyzing asset allocation by location and vendor.\n- Monitor asset status (new, under repair, etc.).\n\n**DBMS:** SQLite 3.47.2\n\n\n---\n\n\u003cdiv class=\"columns\"\u003e\n\n\u003cdiv class=\"column\"\u003e\n\n**Ожидаемые пользователи:**\n- IT-специалисты и администраторы — для учёта оборудования, отслеживания ремонтов, обновлений, закупок.\n- Руководители отделов — для просмотра назначений, списков сотрудников, планирования потребностей.\n- Аналитики — для построения отчётов о распределении и использовании активов.\n\u003c/div\u003e\n\n\u003cdiv class=\"column\"\u003e\n\n**Примеры запросов:**\n- Поиск всех активов, закреплённых за конкретным сотрудником.\n- Список поставщиков, связанных с конкретными типами оборудования.\n- Подсчёт количества активов в отделе по состоянию.\n- Выявление неиспользуемых активов.\n-\tИстория ремонтов по каждому активу.\n\n\u003c/div\u003e\n\u003c/div\u003e\n\n---\n\nСвязи: \n-\t`Employee-Assignment-Asset` тернарная (n:1:m), где `Employee-Assignment` (m:1), `Assignment-Asset` (n:1), `Employee-Asset`(m:n)\n-\t`Asset-Vendor` (n:m)\n-\t`Employee-Department` (n:1)\n-\t`Department-Location` (n:1)\n-\t`Department-Asset` (1:n).\n\nСлабая сущность: `Maintenance` (зависит от Assignment).\n\nРекурсивная связь: `Employee` (отношение \"Руководитель-Подчиненный\", 1:n)\n\n\n---\n### ER-диаграмма\n\u003c!-- _class: box image-slide --\u003e\n\nERD Chen-notation\n\n![Диаграмма](pics/result.drawio.svg)\n\n---\n### ER-диаграмма\n\n\u003c!-- _class: box image-slide --\u003e\n\n\u003cimg src=\"pics/db.png\" alt=\"диаграмма\"\u003e\n\n---\n\u003c!-- _class: box image-slide --\u003e\n\n### Связи Asset\n\n![alt text](pics/asset_key.png)\n\n---\n\n\u003c!-- _class: box image-slide --\u003e\n\n### Связи Asset-Vendor\n![alt text](pics/asset_vendor_key.png)\n\n\n---\n\n\n\u003c!-- _class: box image-slide --\u003e\n\n### Связи Employee\n\n![alt text](pics/employee_key.png)\n\n---\n\n## Нормализация\n\n- Все отношения в 3NF\n- Каждый атрибут зависит только от ключа, нет транзитивных зависимостей\n- Тернарная связь `Assignment–Employee–Asset` вынесена в отдельную таблицу Assignment\n- N:M связь `Asset–Vendor` оформлена отдельной таблицей\n- Атрибуты атомарны: поля разделены (city/address, first_name/last_name)\n- Слабая сущность `Maintenance` связана через ключ с Assignment ⇒ никакого дублирования\n- Отсутствуют агрегатные и вычисляемые поля внутри таблиц\n\nВсе нетривиальные зависимости устранены ⇒ достигается 4NF\n\n---\n### Создание таблиц\n\n`Assignment`\n\n\u003cdiv class=\"columns\"\u003e\n\u003cdiv class=\"column\"\u003e\n\n```sql\nCREATE TABLE Assignment (\n    assignment_id INTEGER PRIMARY KEY AUTOINCREMENT,\n    employee_id INTEGER NOT NULL,\n    asset_id INTEGER NOT NULL,\n    from_date DATE NOT NULL,\n    to_date DATE,\n    type TEXT CHECK(type \n      IN ('Permanent', 'Temporary')),\n    FOREIGN KEY \n      (employee_id) REFERENCES Employee(employee_id) \n      ON DELETE CASCADE,\n    FOREIGN KEY \n      (asset_id) REFERENCES Asset(asset_id) \n      ON DELETE CASCADE\n);\n```\n\n\u003c/div\u003e\n\n\u003cdiv class=\"column2\"\u003e\n\u003cimg src=\"pics/image.png\" alt=\"диаграмма\" width=\"50%\" style=\"align-center\"\u003e\n\n\u003c/div\u003e\n\u003c/div\u003e\n\n---\n\n### Заполнение таблиц\n```sql\nINSERT INTO Assignment (employee_id, asset_id, from_date, to_date, type) VALUES\n(1, 1, '2023-01-15', NULL, 'Permanent'),\n(2, 2, '2023-03-10', '2023-12-01', 'Temporary'),\n(3, 3, '2023-05-20', NULL, 'Permanent'),\n(4, 4, '2023-07-01', '2023-11-30', 'Temporary'),\n(5, 5, '2023-09-15', NULL, 'Permanent'),\n(6, 6, '2023-02-01', NULL, 'Permanent');\n```\n\n\u003cbr\u003e\n\n![alt text](pics/assignment_table.png)\n\n\n---\n\n### Некоторые запросы. CTE + рекурсия\n\n\n```sql\n/* Построение иерархии сотрудников, начиная с тех, у кого нет руководителя, \nи рекурсивно добавляет подчинённых с указанием уровня в иерархии.*/\nWITH RECURSIVE EmployeeHierarchy AS (\n    SELECT employee_id, name, surname, manager_id, 0 AS level -- нач. ур. иерархии\n    FROM Employee\n    WHERE manager_id IS NULL -- самые верхние в иерархии\n    UNION ALL\n    SELECT e.employee_id, e.name, e.surname, e.manager_id, eh.level + 1\n    FROM Employee e\n    INNER JOIN EmployeeHierarchy eh ON e.manager_id = eh.employee_id)\nSELECT * FROM EmployeeHierarchy ORDER BY level, surname, name;\n```\n\u003cimg src=\"pics/cte_res.png\" width=\"50%\"\u003e\n\n---\n### Некоторые запросы. VIEW\n\n\n```sql\n/* Получить список городов, максимальную вместимость департаментов и \nсреднюю стоимость оборудования, которым владеет департамент. Добавить \nстолбец big_city (True / False), еслит суммарная  вместимость в городе \nпо департаментам не менее 40 человек.\n*/\nSELECT l.city,  MAX(d.capacity) AS max_capacity, \n  AVG(a.cost) AS avg_asset_cost,\nCASE \n  WHen MAX(d.capacity) \u003e= 40 then 'True'\n  ELSE 'False'\n  END as big_city\nFROM Location l\nINNER JOIN Department d ON l.location_id = d.location_id\nINNER JOIN Asset a ON d.dept_id = a.dept_id\nGROUP BY l.city\nORDER BY max_capacity DESC;\n```\n---\n\n### Некоторые запросы\n\n\n```sql\n/* Нужно создать представление для оборудования и поставщиков, \nзатем вывести отчет с количеством оборудования по поставщикам.\n*/\n\nCREATE VIEW AssetVendorSummary AS\nSELECT a.name AS asset_name, a.type, v.name AS vendor_name\nFROM Asset a\nINNER JOIN Asset_Vendor av ON a.asset_id = av.asset_id\nINNER JOIN Vendor v ON av.vendor_id = v.vendor_id;\n\nSELECT vendor_name, COUNT(asset_name) AS asset_count\nFROM AssetVendorSummary\nGROUP BY vendor_name\nORDER BY asset_count DESC;\n```\nVIEW для объединения активов и поставщиков. \nВыводим отчет с количеством активов по поставщикам.\n\n---\n\n### Оконные функции\n\n```sql\n/* Для каждого департамента вывести список \nсотрудников с их порядковым номером (по алфавиту имени).*/\nSELECT e.name || ' ' || e.surname AS full_name,\n    d.name AS department_name,\n    ROW_NUMBER() OVER (PARTITION BY e.dept_id \n    ORDER BY e.name, e.surname) AS rank_in_department\nFROM Employee e\nJOIN Department d ON e.dept_id = d.dept_id;\n```\nФормируем отчетность по сотрудникам, которые получили оборудование в департаменте.\n\n---\n### Оконные функции\n\n\n\u003cimg src=\"pics/workers_list.png\" width=\"90%\"\u003e\n\n\n---\n### Оконные функции\n\n```sql\n/* Для каждого актива посчитать, насколько его цена отличается от средней \nпо департаменту.*/\nSELECT \n    a.name AS asset_name,\n    d.name AS department_name,\n    a.cost,\n    ROUND(AVG(a.cost) OVER (PARTITION BY a.dept_id), 2) AS avg_cost_in_dept,\n    ROUND(a.cost - AVG(a.cost) OVER (PARTITION BY a.dept_id), 2) AS diff_from_avg\nFROM Asset a\nJOIN Department d ON a.dept_id = d.dept_id;\n```\n\nСмотрим на отклонение стоимости актива от средней по департаменту может использоваться для оптимизации закупок и выявления нестандартных закупочных решений, если оборудование слишком дорогое / слишком дешевое.\n\n---\n\n### Триггеры\n\n```sql\n\n/* Проверка вместимости департамента: предотвращает добавление сотрудника \nв департамент, если его вместимость уже превышена.*/\n\nCREATE TRIGGER check_department_capacity\nBEFORE INSERT ON Employee\nFOR EACH ROW\nWHEN (\n    (SELECT COUNT(*) FROM Employee WHERE dept_id = NEW.dept_id) \u003e=\n    (SELECT capacity FROM Department WHERE dept_id = NEW.dept_id)\n)\nBEGIN\n    SELECT RAISE(FAIL, 'Department capacity exceeded');\nEND;\n\n```\n\n---\n### Проверка\n\n```sql\nINSERT INTO Department (name, capacity, location_id) VALUES\n('Аналитика', 2, 1);\n\n\nINSERT INTO Employee (name, surname, email, dept_id, manager_id) VALUES\n('Илья', 'Желтый', 'yellow@example.com', 6, NULL),\n('Кирилл', 'Зеленый', 'green@example.com', 6, 1),\n('Михайло', 'Оранжевый', 'orange@example.com', 6, 1); -- вылезет ошибка\n```\n![alt text](pics/image-2.png)\n\n---\n\n### Триггеры\n\n```sql\n/* Триггер для обновления состояния актива на 'Working' \nпосле записи об обслуживании. После добавления записи в Maintenance \nтриггер автоматически обновляет состояние актива на 'Working', если ранее \nоно было 'Repair'*/\n\nCREATE TRIGGER update_asset_condition\nAFTER INSERT ON Maintenance\nFOR EACH ROW\nBEGIN\n    UPDATE Asset\n    SET condition = 'Working'\n    WHERE asset_id = (\n        SELECT asset_id \n        FROM Assignment \n        WHERE assignment_id = NEW.assignment_id\n    )\n    AND condition = 'Repair';\nEND;\n```\n\n---\n\n## Итоги по запросам\n- 16 запросов, куда входят 1 CTE c рекурсией для построения иерархии, 1 VIEW.\n\n- 2 запроса с триггерами: один – для проверки вместимости департамента (нельзя добавить сотрудников больше, чем может быть в департаменте), второй – для обновления состояния актива после его обслуживания.\n\n- 3 оконные функции.\n\nСм. файлы [queries](queries.sql).\n\n---\n\n## Перспективы развития\n\n- Добавить более сложные связи между сущностями\n- Автоматизировать отчётность по оборудованию\n- Реализовать визуализацию аналитики (графики, дашборды)\n\nАвтоматизация и визуализация выходят за рамки курса, но интересны для дальнейшего развития проекта\n\n---\n\n\u003c!-- _class: title-box --\u003e\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbar1o%2Fit-asset-management","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbar1o%2Fit-asset-management","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbar1o%2Fit-asset-management/lists"}