[Funix] Đề cương môn DEP302x

Cách truy cập bài viết:
– Tìm kiếm trên trang cuhuuhoang.com
– Mật khẩu các bài viết [Funix] là mentor

Mục Lục

o1 Khái niệm về kỹ thuật dữ liệu và hệ sinh thái kỹ thuật dữ liệu

Hệ sinh tháidữ liệu bao gồm một mạng lưới các thành phần được kết nối với nhau và liên tục phát triển bao gồm:

  • Dữ liệu: Có sẵn ở nhiều định dạng, cấu trúc và nguồn khác nhau.
  • Môi trường Dữ liệu Doanh nghiệp: Trong đó dữ liệu thô được tổ chức, sắp xếp, làm sạch và tối ưu hóa để người dùng cuối sử dụng.
  • Người dùng cuối: Các bên liên quan kinh doanh, nhà phân tích và lập trình viên, những người sử dụng dữ liệu cho các mục đích khác nhau.

Trong một hệ sinh thái dữ liệu sẽ có rất nhiều vai trò với từng nhiệm vụ khác nhau:

Vai tròCông việcCác kỹ năng cần có
Data Engineer (Kỹ sư dữ liệu)Xây dựng, bảo trì các kiến trúc dữ liệu và chuyển hóa dữ liệu để phù hợp cho việc phân tích nghiệp vụ.– Kiến thức tốt về lập trình.
– Biết rõ về các cơ sở dữ liệu quan hệ và phi quan hệ.
Data Analyst– Dựa vào các dữ liệu đã được xử lý để thu thập thông tin chi tiết.
– Xác định các mối tương quan, tìm các Pattern và áp dụng các phương pháp thống kê để phân tích và khai thác dữ liệu.
Trực quan hóa dữ liệu.
– Kỹ năng lập trình.
– Có kiến thức tốt về việc sử dụng bảng tính, viết truy vấn, sử dụng công cụ xác xuất để tạo dashboard và các biểu đồ.
– Có khả năng truyền đạt tốt.
Data ScientistXây dựng các mô hình chuẩn đoán dựa vào các dữ liệu có sẵn bằng Machine Learning hoặc Deep Learning.– Có kiến thức về Toán và Xác Xuất.
– Có kiến thức về lập trình, sử dụng Database và xây dựng các mô hình dữ liệu.
– Các kiến thức nghiệp vụ.
Bussiness Analyst và BI AnalystLàm việc với Data Analyst và Data Scientist để có cái nhìn tổng quan về mặt nghiệp vụ. Từ đó xác định được các công việc cần phải triển khai tiếp theo để phát triển doanh nghiệp.– Các kiến thức nghiệp vụ.

Data Engineer (Kỹ sư dữ liệu)

Nhiệm vụ của các Kỹ sư dữ liệu:

  • Xây dựng, bảo trì các kiến trúc dữ liệu
  • Chuyển hóa dữ liệu để phù hợp cho việc phân tích nghiệp vụ.
  • Mục tiêu là cung cấp dữ liệu chất lượng để tìm hiểu thực tế và ra quyết định kinh doanh.

Các công việc chính của Kỹ sư dữ liệu:

  • Thu thập dữ liệu: Lấy dữ liệu từ nhiều nguồn khác nhau, đồng thời thiết kế các kiến trúc để lưu trữ dự liệu.
  • Xử lýdữ liệu: Làm gọn, chuyển hóa và chuẩn bị dữ liệu để có thể sử dụng được. Bao gồm các bước như Trích Xuất – Chuyển Hóa – Tải dữ liệu.
  • Lưu trữ dữ liệu: Bạn cần lưu trữ lại các dữ liệu đã được xử lý, hệ thống lưu trữ cần đảm bảo về tính khả mở cũng như bảo mật.
  • Xử lý dữ liệu để người dùng có thể sử dụng: Bạn cần thiết kế các API, các dịch vụ hoặc các Dashboard để người dùng có thể dễ dàng truy cập vào các dữ liệu cần thiết.

Kỹ sư dữ liệu cần có sự kết hợp của các Kỹ năng chuyên môn và các Kỹ năng mềm.

  • Kỹ năng chuyên môn bao gồm
    • Làm việc với các hệ điều hành và các cơ sở hạ tầngkhác nhau như máy ảo, mạng và dịch vụ ứng dụng
    • Làm việc với cơ sở dữ liệu và Data Warehouse, Data Pipeline, công cụ ETL, Big Data và ngôn ngữ để truy vấn, thao tác và xử lý dữ liệu.
  • Các kỹ năng nghiệp vụbao gồm
    • Khả năng chuyển đổicác yêu cầu nghiệp vụ thành các đặc điểm kỹ thuật
    • Hiểu biết về vòng đời phát triển phần mềm và các lĩnh vực chất lượng dữ liệu, quyền riêng tư, bảo mật và quản trị.
  • Kỹ năng mềm bao gồm các kỹ năng giao tiếp giữa các cá nhân, khả năng làm việc hợp tác, làm việc nhóm và giao tiếp hiệu quả.

Hệ sinh thái Kỹ thuật Dữ liệu

Hệ sinh thái của Kỹ thuật dữ liệu bao gồm cơ sở hạ tầng, công cụ, khuôn khổ và quy trình để trích xuất dữ liệu, lưu trữ và quản lý quy trình dữ liệu và Data Warehouse, quản lý quy trình công việc, phát triển ứng dụng và quản lý các công cụ BI báo cáo.

Các dữ liệu có thể được chia ra thành ba loại như sau:

  • Dữ liệu có cấu trúc: Dữ liệu có định dạng có thể lưu xuống cơ sở dữ liệu.
  • Dữ liệu bán cấu trúc: Dữ liệu có một phần là cấu trúc, một phần là tự do.
  • Dữ liệu phi cấu trúc: Dữ liệu không thể đưa về dạng bảng để lưu trong cơ sở dữ liệu.

Dữ liệu có nhiều định dạng tệp khác nhau, chẳng hạn như tệp văn bản được phân tách, bảng tính, XML, PDF và JSON. Dữ liệu cũng được trích xuấttừ nhiều nguồn dữ liệu, từ cơ sở dữ liệu quan hệ và phi quan hệ, đến API, dịch vụ web, luồng dữ liệu, nền tảng xã hội và thiết bị cảm biến.

Trong việc phát triển các Kho dữ liệu, thường có hai loại chính là OLTP(On-line transactional processing) và OLAP (On-line analytical processing).

  • OLTP được thiết kế để lưu trữ một khối lượng lớn dữ liệu hoạt động hàng ngày như giao dịch ngân hàng trực tuyến, giao dịch ATM và đặt vé máy bay. Mục đích của OLTP chính là bảo đảm tính chính xác và tính toàn vẹn của các giao dịch, hoạt động.
  • OLAP được tối ưu hóa để tiến hành phân tích dữ liệu phức tạp. OLAP cho phép chúng ta tìm ra xu hướng, điểm mấu chốt thường phục vụ cho các mục đích phân tích.

Các chuyên gia dữ liệu cần các ngôn ngữ có thể giúp họ trích xuất, chuẩn bị và phân tích dữ liệu. Ví dụ:

  • Ngôn ngữ truy vấn được thiết kế để truy cập và thao tác dữ liệu trong một cơ sở dữ liệu, ví dụ: SQL,…
  • Ngôn ngữ lập trình được thiết kế để phát triển các ứng dụng và kiểm soát hành vi ứng dụng như Python, Java,…
  • Unix/Linux Shellđược thiết kế cho các tác vụ lặp đi lặp lại gây tốn nhiều thời gian.

o2  Nắm được khái niệm về các thành phần trong hệ sinh thái dữ liệu

Data Repositories là một thuật ngữ chung đề cập đến dữ liệu đã được thu thập, tổ chức và trích xuất để nó có thể được sử dụng cho báo cáo, phân tích và cũng cho mục đích lưu trữ. Có một số loại Data Repositories như sau:

  • Database: Có thể là cơ sở dữ liệu quan hệ hoặc phi quan hệ.
  • Data Warehouse: Tổng hợp và chuyển đồi các dữ liệu từ nhiều nguồn khác nhau.
  • Data Lake: Tương tự như Data Warehouse, nhưng dữ liệu sẽ không được xử lý mà đưa thẳng vào luôn.
  • Data Mart: Là một dạng nhỏ hơn của Data Warehouse, các dữ liệu chỉ tập trung vào một lĩnh vực duy nhất.
  • Big Data Stores: Cung cấp cơ sở hạ tầng lưu trữ và tính toán phân tán để mở rộng quy mô và xử lý các tập dữ liệu rất lớn.

Database có thể được chia ra làm 2 loại chính là:

  • RDBMS: Viết tắt của Relational Database Management System (Hệ thống quản lý cơ sở dữ liệu quan hệ). Trong RDBMS, dữ liệu được biểu diễn bởi các hàng. Nó chứa các bảng và mỗi bảng có Primary Key riêng, bởi vì các bảng này được tổ chức chặt chẽ nên việc truy cập dữ liệu trở nên dễ dàng hơn trong RDBMS thông qua ngôn ngữ SQL.
  • NoSQL: Là một dạng cơ sở dữ liệu sử dụng cho các dữ liệu phi cấu trúc, dữ liệu thường có thể được biểu diễn ở dạng Document, Key-Value, Graph hoặc là Column. NoSQL mang đến một số ưu điểm về tốc độ truy vấn cũng như tốc độ thực hiện các thao tác CRUD dữ liệu, đồng thời cũng có thể được mở rộng và chạy trên nhiều cụm máy khác nhau.

o3  Biết được các công cụ hỗ trợ trong kỹ thuật dữ liệu

Nền tảng tích hợp dữ liệukết hợp các nguồn dữ liệu khác nhau, về mặt vật lý hoặc logic, để cung cấp một cái nhìn thống nhất về dữ liệu cho các mục đích phân tích. Tích hợp dữ liệu (Data Intergration) bao gồm các công việc như sau:

  • Truy cập, truy vấn và trích xuất dữ liệu.
  • Chuyển đổi và hợp nhất dữ liệu vừa được trích xuất.
  • Quản lý về chất lượng của dữ liệu.
  • Cung cấp dữ liệu thông qua các cách tích hợp cho mục đích phân tích.

Quy trình Kỹ thuật dữ liệu

Kiến trúc của nền tảng dữ liệu có thể được xem như một tập hợp các tầng hoặc các thành phần chức năng, mỗi lớp thực hiện một tập hợp các nhiệm vụ cụ thể.

  • Tầng thu thập dữ liệu: chịu trách nhiệm đưa dữ liệu từ nguồn dữ liệu vào nền tảng dữ liệu.
  • Tầng tích hợp và lưu trữdữ liệu: chịu trách nhiệm lưu trữ và hợp nhất dữ liệu đã trích xuất.
  • Tầng xử lý dữ liệu: chịu trách nhiệm xác thực, chuyển đổivà áp dụng các quy tắc nghiệp vụ cho dữ liệu.
  • Tầng phân tích giao diện người dùng: chịu trách nhiệm cung cấp dữ liệu đã xử lý cho người tiêu dùng dữ liệu.
  • Tầng Data Pipeline(đường ống dữ liệu): chịu trách nhiệm triển khai và duy trì quy trình.

Data Store hay Data Repositories là một thuật ngữ chung đề cập đến dữ liệu đã được thu thập, sắp xếp và tách biệt để nó có thể được sử dụng cho báo cáo, phân tích và cũng cho mục đích lưu trữ.

Việc lựa chọn hoặc thiết kế một Data Store ảnh hưởng bởi loại dữ liệu và khối lượng dữ liệu cần được lưu trữ, mục đích sử dụng dữ liệu. Các nhu cầu về quyền riêng tư, bảo mật và quản trị của tổ chức của bạn cũng ảnh hưởng đến sự lựa chọn này.

Chúng ta sẽ có từng cách riêng biệt để có thể thu thập được dữ liệu từ các Data Source khác nhau:

  • SQL Query:bạn có thể sử dụng SQL để truy vấn và lấy dữ liệu từ các Database, đồng thời SQL cũng hỗ trợ các theo tác như Group, Count,… Với các Database thuộc dạng NoSQL thì cũng sẽ có các công cụ truy vấn tương ứng như GraphQL,…
  • API: API thường được sử dụng để thu thập dữ liệu từ các data source, khi được thực thi từ các ứng dụng cần dữ liệu, API sẽ truy cập vào Database, truy vấn và trả về dữ liệu cần thiết.
  • Web Scraping: Là phương pháp thu thập, trích xuất dữ liệu dạng text, ảnh, video,… từ các trang Web.
  • Data Stream:Là phương pháp để tổng hợp các dữ liệu liên tục, phù hợp để thu thập các dữ liệu từ IoT, cảm biến, hoặc các ứng dụng thời gian thực.
  • Data Exchanges: Cho phép trao đổidữ liệu giữa bên cung cấp và bên cần sử dụng dữ liệu.

Làm gọn dữ liệu liên quan đến loạt các hoạt động biến đổi và làm sạch được thực hiện trên dữ liệu. Chuyển đổi dữ liệu thô bao gồm các nhiệm vụ bạn thực hiện như sau:

  • Kết hợp các dữ liệu bằng các thao tác Joins và Unions.
  • Chuẩn hóa dữ liệu, tức là làm sạch cơ sở dữ liệu của dữ liệu thừa.
  • Kết hợp dữ liệu từ nhiều bảng thành một bảng duy nhất để có thể truy vấn nhanh hơn.

Sau khi đã nhập dữ liệu thành công thì dữ liệu đó đã có thể được phân tích. Chúng ta cũng có một số thao tác phân tích dữ liệu cơ bản như sau:

  • Counting: Đếm số lượng Row, Record trong tập dữ liệu.
  • Aggregation: Tổng hợp dữ liệu từ nhiều khía cạnh khác nhau để có một cái nhìn tổng quát hơn.
  • Extreme ValueIdentification: Xác định các cực trị trong dữ liệu, ví dụ như MIN, MAX, …
  • Slicing Data: Tìm các dữ liệu dựa trên một tập các điều kiện.
  • Sorting Data: Sắp xếp lại dữ liệu dựa trên các điều kiện.
  • Filtering Patterns: Lọc các dữ liệu cần thiết

Trong vòng đời kỹ thuật dữ liệu, hiệu suất của Data Pipelines, các nền tảng, Databases, ứng dụng, công cụ, truy vấn, and lập lịch cần phải được theo dõi liên tục về hiệu suất và tính khả dụng. 

  • Hiệu suất của Data Pipelines có thể bị ảnh hưởng nếu khối lượng công việc tăng lên đáng kể hoặc có lỗi ứng dụng hoặc các Task đã lên lịch không hoạt động như mong đợi, một số công cụ trong Data Pipelines gặp sự cố tương thích.
  • Cơ sở dữ liệu dễ bị ngừng hoạt động, sử dụng quá mức dung lượng, ứng dụng chạy chậm, các truy vấn bị xung đột khi thực thi đồng thời.

Vì vậy mà chúng ta cần một hệ thống giám sát hiệu suất. Hệ thống giám sát và cảnh báo sẽ thu thập dữ liệu định lượng trong thời gian thực để cung cấp khả năng hiển thị về hiệu suất của Data Pipelines, nền tảng, Databases, ứng dụng, công cụ, truy vấn, lập lịch,… Và cũng cần có lịch trình bảo trì dựa trên thời gian và điều kiện tạo ra dữ liệu giúp xác định các hệ thống và quy trình chịu trách nhiệm về lỗi và tính khả dụng thấp.

o4  Hiểu rõ các cơ hội về nghề nghiệp cũng như định hướng tương lai trong lĩnh vực kỹ thuật dữ liệu.

Kỹ sư dữ liệu có thể đảm nhiệm rất nhiều vai trò trong, các vai trò này sẽ phụ thuộc vào công ty mà bạn làm việc, tuy nhiên thông thường sẽ được chia thành các mảng như sau:

Từ đó cũng sẽ có những vai trò trong Kỹ Thuật Dữ Liệu như sau:

o5  Nắm được các khái niệm về Data Warehouse cũng như một số môi trường dữ liệu khác

Data Warehouse là một kỹ thuật thu thập và quản lý dữ liệu từ nhiều nguồn khác nhau để cung cấp những thông tin kinh doanh có ý nghĩa.

Các tính chất của Data Warehouse

  • Được tích hợp (Integrated): Dữ liệu trong Data Warehouse sẽ được lấy từ nhiều nguồn dữ liệu (Data Source) khác nhau để có được đầy đủ thông tin.
  • Hướng chủ đề (Subject oriented): Tổ chức dữ liệu theo chủ đề để thuận tiện cho việc phân tích. Ví dụ với chủ đề phân tích nhân sự thì có thể bao gồm các độ đo về doanh thu của từng người, số ngày nghỉ trong tháng, số dự án tham gia trong tháng,… theo các chiều phân tích: thời gian, chi nhánh, sản phẩm,… Chỉ lưu trữ các dữ liệu cần thiết cho công việc phân tích, không cần những dữ liệu thừa khác.
  • gán nhãn thời gian (Time variant): Các dữ liệu sẽ được gán một nhãn thời gian tương ứng để có thể lưu lại được các dữ liệu lịch sử (Historical data). Dữ liệu lịch sử có tầm quan trọng đặc biệt trong phân tích dữ liệu, cùng một độ đo sẽ có nhiều giá trị khác nhau trong lịch sử có thể dùng để so sánh với nhau để biết được sự thay đổi là tốt hay xấu.
  • Bất biến (Non volatile): Khác với Database thì Data Warehouse chỉ có hai thao tác chính là đọc và ghi dữ liệu. Dữ liệu sẽ không thể bị thay đổi, cập nhật do như vậy sẽ không phản ánh đúng với thực tế.

Các lợi ích khi sử dụng Data Warehouse:

  • Hỗ trợ đưa ra quyết định theo hướng dữ liệu.
  • One Stop Shopping: Tất cả dữ liệu (từ nhiều nguồn khác nhau) được tập trung về một chỗ. Giúp cho ta có chỉ cần tập trung vào việc phân tích dữ liệu mà không cần phải lo việc thu thập dữ liệu nữa.

Một số điểm khác biệt giữa Data Warehouse và Data Lake:

Data WarehouseData Lake
– Data Warehouse thường được xây dựng trên một cơ sở dữ liệu quan hệ (Relational Database) hoặc hệ cơ sở dữ liệu đa chiều (Multidimensional Database).
– Data warehouse biến đổi và phân loại dữ liệu từ các nguồn khác nhau của doanh nghiệp. Dữ liệu này sẽ sẵn sàng để phục vụ cho các mục đích khác, đặc biệt là báo cáo và phân tích.
– Gồm các dữ liệu có cấu trúc cụ thể.
– Data Lake thường được xây dựng trên một môi trường Big Data.
– Data Lake lưu trữ dữ liệu chưa qua phân tíchvà giữ trong trạng thái thô. Những dữ liệu này cần được xử lý thêm khi có nhu cầu sử dụng.
– Có thể chứa tất cả các loại dữ liệu.

Một khái niệm khác hay bị nhầm với Data Warehouse là Data Virtualization. Một số điểm khác biệt của Data Virtualization như sau:

  • Là một cơ sở dữ liệu quan hệ Read only (các dữ liệu chỉ đọc).
  • Trong quá trình phân tích, thống kê thì sẽ truy cập trực tiếp vào Database thay vì phải sao chép dữ liệu về một chỗ khác.

Từ đó, chúng ta có thể thấy được Data Virtualization nên được sử dụng trong các trường hợp sau:

  • Không yêu cầu các phép biến đổi dữ liệu quá nặng.
  • Số lượng nguồn dữ liệu ít.
  • Thời gian thực hiện truy vấn không quá quan trọng.

Quy trình hoạt động của một môi trường Data Warehouse:

  • Dữ liệu từ nhiều nguồn (data source) qua quá trình ETL – Extract (Trích xuất), Load (Tải lên), and Transform (Chuyển đổi) sẽ được đưa vào Data Warehouse.
  • Đôi khi, các dữ liệu sẽ được tiếp tục chuyển đến cho các môi trường nhỏ hơn như Data Mart

o6  Lựa chọn được các kiến trúc phù hợp để xây dựng môi trường Data Warehouse

Centralized Data Warehouse: Là một môi trường chỉ gồm một Data Warehouse duy nhất, tất cả các dữ liệu đều được lưu ở đây. Kiến trúc này mang đến một số ưu điểm sau:

  • One Stop Shopping (một điểm dừng): Tất cả dữ liệu (từ nhiều nguồn khác nhau) được tập chung về một chỗ giúp việc phân tích dễ dàng hơn.
  • Dễ dàng vẽ các sơ đồ thiết kế.

Như bài trước đã giới thiệu, dữ liệu sẽ không cần dừng lại ở Data Warehouse mà có thể chuyển xuống các môi trường nhỏ hơn như Data Mart. Data mart là một tập hợp nhỏ của Data Warehouse, thường chỉ tập chung vào 1 lĩnh vực duy nhất, ví dụ như Data Mart về sale, về khách hàng,…

Data Mart sẽ nhỏ và linh hoạt hơn. Khi phân tích về một lĩnh vực nhỏ thì sẽ chỉ cần dùng dữ liệu từ Data Mart tương ứng chứ không cần tìm trong Data Warehouse.

Có 2 loại Data Mart:

Dependent Data Mart (phụ thuộc)Independent Data Mart (độc lập)
– Dữ liệu được lấy từ Data Warehouse.
– Các dữ liệu sẽ đồng nhất với nhau.
– Dữ liệu được lấy trực tiếp từ các data source.
– Các dữ liệu không nhất thiết phải đồng nhất với nhau.

Như vậy thì Data Warehouse sẽ khá giống với Independent Data Mart, ta có những sự khác biệt như sau:

Data WarehouseIndependent Data Mart
– Dữ liệu được lấy từ rất nhiều nguồn.– Dữ liệu được lấy từ một số nguồn.

Khác với Centralized, kiến trúc Component-Basedsẽ gồm nhiều thành phần (Data Warehouse, Data Mart hoặc Data Lake) liên kết lại với nhau.

Để lựa chọn được kiến trúc phù hợp nhất, đầu tiên ta cần chọn giữa Centralized và Component-Based

CentralizedComponent-Based
Ưu điểm– Là phương án mặc định.
– One Stop Shopping.
– Công nghệ hiện đại.
– Hỗ trợ Mix-and-Match
– Có thể liên kết các thành phần với nhau.
– Dễ xử lý các vấn đề liên quan đến lưu trữ dữ liệu.
Nhược điểm– Các tổ chức cần liên kết chặt chẽ với nhau,
Khả năng quản lý dữ liệu phải tốt.
– Có thể xảy ra ripple effect. Khi một dữ liệu thay đổi có thể ảnh hưởng đến toàn bộ dữ liệu.
– Các dữ liệu thường không nhất quánvới nhau.
– Khó để tích hợp chéo.

Ngoại trừ cơ sở dữ liệu quan hệ (RDBMS), ta còn có thể sử dụng cơ sở dữ liệu đa chiều (MDBMS). MDBMS thường sẽ phù hợp với các Data Warehouse có quy mô nhỏ.

Ưu điểmNhược điểm
– Thời gian truy xuất dữ liệu nhanh.
– Dung lượng lưu trữ không quá lớn.
– Cấu trúc ít linh hoạt hơn RDBMS.
– Có nhiều sự biến thể hơn RDBMS.

Ngoài Data Warehouse, ta còn có thể sử dụng ODS (Operational Data Store). ODS giống như Data warehouse nhưng khi dữ liệu được cập nhật sẽ ghi đè lên dữ liệu => ODS sẽ không có các dữ liệu lịch sử (Historical Data).

o7  Hiểu được các thành phần trong Data Warehouse

Staging Layer (tầng trung gian): Là khu vực trung gianthực hiện việc xử lý thông tin cũng như lưu trữ trước khi đưa vào Data Warehouse.

User Access Layer(tầng người dùng truy cập): Là khu vực mà user có thể truy cập được vào dữ liệu.

Staging Layer được chia ra làm hai loại:

Non Persistent (không liên tục)Persistent (Liên tục)
Định nghĩa– Sau khi đưa dữ liệu vào Data Warehouse thì sẽ xóa dữ liệu cũ ở Staging Layer đi.– Sau khi đưa dữ liệu vào Data Warehouse thì vẫn giữ dữ liệu cũ ở Staging Layer.
Ưu điểmLưu trữ ít hơn.
– Dữ liệu được chuyển hẳn sang User Layer.
– Khi User Layer gặp lỗivà cần dựng lại thì có thể lấy trực tiếp dữ liệu từ Staging Layer.
– Để đảm bảo chất lượng dữ liệu thì chỉ cần so sánh giữa User Layer và Staging Layer.
Nhược điểm– Khi User Layer gặp lỗi và cần dựng lại thì sẽ phải lấy lại các dữ liệu từ Data Source.
– Việc đảm bảo chất lượng dữ liệu cũng cần đến Data Source.
– Phải lưu trữ nhiều hơn.
– Có rủi ro bị truy cập trái phép.

o8  Hiểu được các loại ETL (Inital Load ETL và Incremental ETL) và cách sử dụng từng loại

BI (Business Intelligence)là một quy trình có khả năng tích hợp công nghệ giúp các doanh nghiệp kiểm soát khối lượng dữ liệu khổng lồ đến từ nhiều nguồn khác nhau và khai thác nguồn dữ liệu đó một cách hiệu quả. Đồng thời hệ thống tạo ra những tri thức (knowledge) mới giúp cho các nhà quản lý có thể đưa ra các quyết định hiệu quả hơn trong hoạt động kinh doanh của mình.

Initial Load ETL(ETL tải ban đầu) là một biến thể của ETL, gồm một số đặc điểm sau:

  • Chỉ xảy ra một lần trước khi Data Warehouse được đưa vào vận hành.
  • Đưa tất cả các dữ liệu cần thiết cho việc phân tích và BI vào Data Warehouse.
  • Có thể thực hiện lại nếu Data Warehouse gặp lỗi và cần khởi động lại.

Incremental ETL

Incremental ETL (ETL gia tăng) cũng là một biến thể của ETL, mục đích là giữ cho các dữ liệu luôn mới nhất bằng cách thêm các dữ liệu mới hoặc cập nhật các giữ liệu cũ. Ngoài ra, Incremental ETL cũng xử lý việc xóa dữ liệu. Lúc này thì dữ liệu sẽ không bị xóa hẳn khỏi Data Warehouse mà chỉ đánh dấu là không còn active nữa.

Bốn thao tác trong Incremental ETL: 

  • Append: Chèn thêm dữ liệu vào Data Warehouse.
  • In-place Update: Thay đổi một số dữ liệu có sẵn.
  • Complete replacement: Thay đổi toàn bộ dữ liệu có sẵn.
  • Rolling append: Thường được sử dụng trong việc quản lý dữ liệu theo thời gian. Khi chèn thêm một dữ liệu mới thì sẽ xóa dữ liệu cũ tương ứng đi.

Thực tế, Data Warehouse sẽ không lấy dữ liệu từ tất cả các Data Source cùng một thời gian, có Data Source sẽ lấy dữ liệu hàng tháng, hoặc hàng giờ,… Và mỗi Data Source cũng sẽ sử dụng một mô hình chuyển đổi khác nhau.

Mix-and-Match (pha trộn và kết hợp) là phương pháp kết hợp nhiều mô hình chuyển đổi với nhau.

o9  Hiểu được khái niệm về ETL để đưa dữ liệu vào Data Warehouse

ETL viết tắt cho:

  • Trích xuất(Extract): Lấy dữ liệu từ các Data Source theo từng lô, bao gồm tất cả dữ liệu thô (chưa qua xử lý) và chuyển đến Staging Layer.
  • Chuyển đổi(Transform): Biến đổi để dữ liệu từ nhiều nguồn đồng nhấtvới nhau. Quá trình này có thể rất phức tạp.
  • Tải (Load): Chuyển các dữ liệu đã được biến đổi vào User Access Layer.

Ngoài ETL thì bạn còn được giới thiệu đến khái niệm về ELT. Khác với ETL thì dữ liệu sau khi được trích xuất thì sẽ lưu xuống Data Lake / Data Warehouse, sau đó các phép Transform mới được thực hiện ở nơi lưu trữ dữ liệu. Quy trình này mang đến một số ưu điểm như sau:

  • Giảm thời gian giữa bước Trích Xuất (Extract) và Phân Phối (Delivery) dữ liệu.
  • Có thể sử dụng dữ liệu thô ngay khi chúng sẵn sàng.
  • Mang đến sự linh hoạt trong việc phân tích/xử lý dữ liệu do dữ liệu chưa được biến đổi gì hết.
  • Bạn chỉ cần thực hiện Transform các dữ liệu cần thiết cho một nhu cầu phân tích cụ thể nào đó.

o10 Xây dựng được một ETL để đưa dữ liệu vào Data Warehouse

(Kiểm tra thực hành)

o11 Sử dụng SSIS để xây dựng ETL

(Kiểm tra thực hành)

o12 Hiểu được tầm quan trọng của việc biến đổi dữ liệu và các phép biến đổi dữ liệu thường dùng

Bước chuyển đổi giúp các dữ liệu đồng nhất với nhau và phù hợp về mặt nghiệp vụ. Do Data Warehouse lấy dữ liệu từ rất nhiều nguồn khác nhau nên bước chuyển đổi này rất quan trọng.

Các mô hình chuyển đổi:

  • Đồng nhất về giá trị.
  • Đồng nhất về loại và kích thước của dữ liệu.
  • Loại bỏ các dữ liệu trùng nhau.
  • Loại bỏ các cột không cần thiết.
  • Loại bỏ các hàng không cần thiết.
  • Sửa các lỗi được phát hiện.

o13 Hiểu đươc khái niệm về Facts, Fact Tables, Dimensions, và Dimension Tables

Để bắt đầu xây dựng một Data Warehouse, thì chúng ta cần dựa vào mục đích sử dụng về mặt nghiệp vụ, từ đó chọn ra được data model sẽ sử dụng.

Facts: Thường là phép đo (measure), số liệu (metrics) hoặc sự kiện (fact) của quy trình kinh doanh (business process).

Ví dụ: điểm số, thù lao, … => Fact Table là một bảng chứa các Fact.

Dimensions: Cung cấp các thông tin, ngữ cảnh cho Fact.

Ví dụ: tên môn học, tên công ty, … => Dimension Table là một bảng chứa các Dimension.

Fact có thể được chia ra làm 3 loại:

  • Additive: là những Fact có thể được tổng hợp thông qua tất cả các Dimension trong Fact Table.
  • Semi-Additive: là những Fact có thể được tóm tắt cho một số Dimension trong Fact Table chứ không phải là những bảng khác. (ví dụ như tài khoản ngân hàng cuối tháng, có thể tính tổng tại một thời điểm nhất định nhưng không thể tính tổng theo người)
  • Non-Additive: là những Fact không được tóm tắtcho bất kỳ Dimension hiện tại nào trong Fact Table. (ví dụ như chỉ số đánh giá rating hay mặt hàng giảm giá bao nhiêu %)

Fact Table được chia thành 4 loại chính:

  • Transaction: Dữ liệu chủ yếu là các Additive Facts được lưu lại từ các giao dịch.
  • Periodic Snapshot: Bảng này lưu trữ Snapshot quy trình kinh doanh trong một khoảng thời giancụ thể.
  • Accumulating Snapshot: Đại diện cho toàn bộ vòng đời của quy trình kinh doanh từ đầu đến cuối quy trình.
  • Factless: Dữ liệu không bao gồm một Fact nào hết.

o14 Hiểu về sự khác nhau về kiến trúc cũng như ưu điểm giữa Star Schemas và Snowflake Schemas

Lược đồ hình sao (Star Schema)Lược đồ bông tuyết (Snowflake Schema)
Định nghĩa– Gồm 1 Fact Table nằm ở trung tâm và được bao quanh bởi những Dimension Table
– Dữ liệu không được chuẩn hoá.
– Là dạng mở rộng của Star Schema bằng cách chuẩn hóa các Dimension Table.
– Dữ liệu được chuẩn hoá.
Ưu điểm– Fact Table, Dimension Table được mô tả rõ ràng, dễ hiểu.
– Khoá của Fact Table được tạo bởi khoá của các Dimension Table. Nghĩa là khoá chính của các Dimension Table chính là khoá của Fact Table.
– Số chiều được phân cấp thể hiện dạng chuẩn của Dimension Table.
– Các Dimension Table sử dụng ít bộ nhớ hơn.
Nhược điểmDữ liệu không được chuẩn hóa.Cần thực hiện các bước JOIN bảng để lấy dữ liệu

o15 Nắm được khái niệm về các loại khóa trong Data Warehouse (Primary Key, Foreign Key, Nature Key và Surrogate Key)

Khóa chính (Primary Key) trong Datawarehouse được chia thành 2 loại:

  • Surrogate Key: Là khóa chính dimension table thường có giá trị là kiểu số. Thường được hệ thống DW sinh ra (duy nhất) bằng các luồng ETL. Tuy nhiên đây là khóa không có ý nghĩa trong ngữ cảnh nghiệp vụ.
  • Natural Key: Là loại khoá sử dụng chính một hoặc kết hợp nhiều thuộc tính có sẵn của đối tượng lưu trữ trong CSDL để làm khoá ⇒ có ý nghĩa trong ngữ cảnh nghiệp vụ.

Primary Key trong Fact Table sẽ là tổng hợp của tất cả các Foreign Key liên kết với các Dimension Table có liên quan (kể cả khi bảng đã có Nature Key).

Foreign Key trong Fact Table sẽ liên kết với các Dimension Table có liên quan.

o16 Có thể thiết kế được Fact Table và Dimension Table phù hợp với dữ liệu

(kiểm tra theo ví dụ đề bài)

o17 Biết cách sử dụng Slowly Changing Dimensions (SCD) để quản lý các dữ liệu lịch sử

3 loại SCD:

Kỹ thuậtTính chất
Loại 1– In-Place Update
– Đơn giản là thay đổi giá trị cũ thành mới
– Đây là loại đơn giản nhất nhưng sẽ không giữ được các dữ liệu cũ.
Loại 2– Khi có thay đổi thì sẽ chèn thêm 1 hàngnữa chứa các giá trị update mới ⇒ Giữ cả 2 version cũ và mới.– Phức tạp về mặt kỹ thuật nhưng sẽ giữ lại được các dữ liệu cũ.
Loại 3– Khi thay đổi giữ liệu thì sẽ có 2 cột, một cột chứa giá trị cũ, một cột chứa giá trị mới.– Ưu điểm: Không tăng kích thước của bảng và có thể giữ lại được các dữ liệu cũ.
– Khuyết điểm: Sẽ không dữ được các dữ liệu cũ nếu dữ liệu bị thay đổi nhiều lần.

Nếu như sử dụng SCD loại 2 thì chúng ta sẽ không biết được đâu là giữ liệu mới nhất. Có một số giải pháp như sau:

  • Current_Flag: Thêm 1 cột current_flag đánh dấu xem đó có phải là giá trị mới nhất không.
  • Eff_date and Exp_date: Thêm 2 cột để thể hiện ngày dữ liệu được thêm và ngày dữ liệu bị thay đổi.

o18 Nắm được ưu, nhược điểm của môi trường Cloud so với On Premise (lưu trữ tại chỗ)

ưu/nhược điểm của Cloud so với việc cài đặt tại chỗ.

Ưu điểmNhược điểm
Giảm tải bảo trìvà cập nhật hệ thống định kỳ.
– Chi phí đầu tư nền tảng có thể thấp hơn.
– Dễ dàng khắc phục các tai nạn hệ thống.
– Có thể kết hợp với Data Lake và Big Data.
– Bảo mật thấp hơn.
– Khó để chuyển dữ liệu từ On-Premises Data Warehouse sang Cloud.
– Khó để chuyển giữa liệu giữa data center và Cloud.

o19 Nắm được cách xây dựng ETL cho Fact Table và Dimension Table

Quy trình ETL cho Dimension Table:

Bước 1: Chuẩn bị dữ liệu(data preparation)

Kỹ thuật “Change Data Capture”.

  • Sử dụng nhãn thời gian. Mỗi dữ liệu sẽ có một nhãn thời gian, ta sẽ so sánh và xem dữ liệu nào đã có từ lần ETL trước và loại dữ liệu đó.
  • So sánh với logtừ database.
  • Phương án cuối cùng là load toàn bộ dữ liệu và so sánh với Data Warehouse để xem dữ liệu nào đã có.

Bước 2: Chuyển hóa dữ liệu

Bước 3: Đưa dữ liệu vào Dimension Table

Nếu đó là một dữ liệu mới hoàn toàn thì chúng ta chỉ cần thêm dữ liệu đó vào Dimension Table. Nếu dữ liệu đó là cập nhật thì chúng ta sử dụng SCD để lưu lại dữ liệu lịch sử

Bước 4: Khi đưa môt dữ liệu mới vào Fact Table, bạn sẽ dựa vào các dữ liệu trong Dimension Table để biết được đâu là Surrogate Key của dữ liệu mới nhất. Tương tự, nếu là các dữ liệu lịch sử được cập nhật thì chúng ta cũng dựa vào Dimension Table để chọn Surrogate Key phù hợp.

o20 Hiểu được các khái niệm về MongoDB và NoSQL

MongoDB là một hệ cơ sở dữ liệu mã nguồn mở thuộc dạng NoSQL. Cấu trúc MongoDB cũng khác với RDBMS:

  • MongoDB chứa các Collection (có thể coi là một Table trong RDBMS).
  • Các Collection này sẽ gồm nhiều Document (mỗi Document sẽ giống như một record trong RDBMS). Các Document sẽ có cấu trúc dạng BSON (khá giống với JSON) và mỗi document không bắt buộc phải có một cấu trúc giống nhau như trong RDBMS. Điều này giúp cho tốc độ truy vấn, xử lý dữ liệu trong MongoDB cũng nhanh hơn so với RDBMS.

Một số ưu điểm của MongoDB:

  • Cấu trúc của một đối tượng rõ ràng.
  • Không có các Join phức tạp.
  • Khả năng mở rộngcực lớn: việc mở rộng dữ liệu mà không phải lo đến các vấn đề như khóa ngoại, khóa chính, kiểm tra ràng buộc,… MongoDB cho phép thực hiện replication và sharding nên việc mở rộng cũng thuận lợi hơn.
  • Ít schemahơn.

o21 Biết cách thực hiện các thao tác Thêm – Đọc – Sửa – Xóa trên MongoDB

Thao tác Thêm

// Thêm một tài liệu vào một collection.
db.products.insertOne({ item: "card", qty: 15 });

// Thêm nhiều tài liệu vào một collection.
db.products.insertMany([
   { item: "card", qty: 15 },
   { item: "envelope", qty: 20 },
   { item: "stamps" , qty: 30 }
]);

Thao tác Đọc

// Tìm tất cả các tài liệu phù hợp với truy vấn.
db.bios.find({ _id: 5 })

// Sử dụng projection để lấy các trường cụ thể trong tài liệu.
db.bios.find({ _id: 5 }, { number: 1, count: 1 })

// Tìm tài liệu đầu tiên phù hợp với truy vấn, với một tham số projection tùy chọn.
db.bios.findOne({ _id: 5 })

// Lựa chọn từ một tài liệu lồng nhau.
db.orders.find({ "address.state": "CA" })

Thao tác Sửa

// Cập nhật dữ liệu của tài liệu đầu tiên phù hợp với truy vấn, sử dụng $set để sửa đổi giá trị của các trường hiện có hoặc $unset để loại bỏ một trường.
db.restaurant.updateOne(
   { "name" : "Central Perk Cafe" },
   { $set: { "violations" : 3 } }
);

db.restaurant.updateOne(
   { "name" : "Central Perk Cafe" },
   { $unset: { "address" : '' } }
);

// Cập nhật tất cả các tài liệu phù hợp với truy vấn, sử dụng $set để sửa đổi giá trị của các trường hiện có hoặc $unset để loại bỏ một trường.
db.books.updateMany(
   { type: 'Commic' },
   { $set: { "Review" : true } }
);

// Thay thế tài liệu đầu tiên phù hợp với truy vấn.
// Chỉ các trường trong tài liệu thay thế sẽ được bao gồm trong tài liệu mới.
db.restaurant.replaceOne(
   { "name" : "Central Perk Cafe" },
   { "name" : "Central Pork Cafe", "Borough" : "Manhattan" }
);

Thao tác Xóa

// Xóa tài liệu đầu tiên phù hợp với truy vấn.
db.orders.deleteOne({ "_id" : 'Order1' });

// Xóa tất cả các tài liệu phù hợp với truy vấn.
db.orders.deleteMany({ "client" : "Crude Traders Inc." });

Thao tác Truy vấn

// $eq: Tìm tài liệu nơi trường "age" bằng 30
db.users.find({ age: { $eq: 30 } })

// $ne: Tìm tài liệu nơi trường "status" không bằng "inactive"
db.users.find({ status: { $ne: "inactive" } })

// $gt: Tìm tài liệu nơi trường "salary" lớn hơn 50000
db.employees.find({ salary: { $gt: 50000 } })

// $gte: Tìm tài liệu nơi trường "rating" lớn hơn hoặc bằng 4
db.products.find({ rating: { $gte: 4 } })

// $lt: Tìm tài liệu nơi trường "price" nhỏ hơn 100
db.products.find({ price: { $lt: 100 } })

// $lte: Tìm tài liệu nơi trường "quantity" nhỏ hơn hoặc bằng 10
db.inventory.find({ quantity: { $lte: 10 } })

// $in: Tìm tài liệu nơi trường "category" là "books" hoặc "electronics"
db.products.find({ category: { $in: ["books", "electronics"] } })

// $nin: Tìm tài liệu nơi trường "status" không phải là "open" hoặc "pending"
db.tickets.find({ status: { $nin: ["open", "pending"] } })

// $or: Tìm tài liệu nơi trường "age" là 30 hoặc 40
db.users.find({ $or: [{ age: 30 }, { age: 40 }] })

// $nor: Tìm tài liệu nơi trường "age" không phải là 30 hoặc 40
db.users.find({ $nor: [{ age: 30 }, { age: 40 }] })

// $and: Tìm tài liệu nơi trường "status" là "active" và trường "role" là "admin"
db.users.find({ $and: [{ status: "active" }, { role: "admin" }] })

// $not: Tìm tài liệu nơi trường "status" không phải là "inactive"
db.users.find({ status: { $not: { $eq: "inactive" } } })

// $exists: Tìm tài liệu nơi trường "email" tồn tại
db.users.find({ email: { $exists: true } })

// $type: Tìm tài liệu nơi trường "age" là kiểu "number"
db.users.find({ age: { $type: "number" } })

// $regex: Tìm tài liệu nơi trường "name" bắt đầu bằng "Joh"
db.users.find({ name: { $regex: /^Joh/ } })

// $expr: Tìm tài liệu nơi giá trị trường "likes" lớn hơn giá trị trường "dislikes"
// Sử dụng $expr khi bạn cần so sánh các trường trong cùng một tài liệu
db.articles.find({ $expr: { $gt: ["$likes", "$dislikes"] } })

// $size: Tìm tất cả các tài liệu mà mảng "hobbies" có đúng 3 phần tử
db.users.find({ hobbies: { $size: 3 } })

// $all: Tìm tất cả các tài liệu mà mảng "tags" chứa các phần tử "electronics" và "smartphone"
db.products.find({ tags: { $all: ["electronics", "smartphone"] } })

// Kết hợp
db.collection('myCollection').find({
  $or: [
    { age: { $gte: 18, $lte: 30 } }, // tìm tài liệu với tuổi từ 18 đến 30
    { occupation: 'student' } // tìm tài liệu với nghề nghiệp là 'student'
  ],
  $and: [
    { salary: { $gte: 50000 } }, // tìm tài liệu có lương >= 50000
    { location: { $regex: /^New York/ } } // tìm tài liệu với địa điểm bắt đầu bằng 'New York'
  ],
  $not: { company: 'Microsoft' } // tìm tài liệu không có công ty = 'Microsoft'
})

// $: Tìm mục đầu tiên trong mảng "items" có tên là "Widget"
db.orders.find({ "items.name": "Widget" }, { "items.$": 1 })

// $elemMatch: Tìm tất cả các đơn hàng có ít nhất một mục có tên là "Widget" và giá lớn hơn 10
db.orders.find({ items: { $elemMatch: { name: "Widget", price: { $gt: 10 } } } })

// $slice: Tìm tất cả các sản phẩm và trả về chỉ 5 phần tử đầu tiên của mảng "reviews" cho mỗi sản phẩm
db.products.find({}, { reviews: { $slice: 5 } })

o22 Biết cách sử dụng các toán tử để thực hiện các thao tác CRUD phức tạp hơn.

// $eq: Tìm tài liệu nơi trường "age" bằng 30
db.users.find({ age: { $eq: 30 } })

// $ne: Tìm tài liệu nơi trường "status" không bằng "inactive"
db.users.find({ status: { $ne: "inactive" } })

// $gt: Tìm tài liệu nơi trường "salary" lớn hơn 50000
db.employees.find({ salary: { $gt: 50000 } })

// $gte: Tìm tài liệu nơi trường "rating" lớn hơn hoặc bằng 4
db.products.find({ rating: { $gte: 4 } })

// $lt: Tìm tài liệu nơi trường "price" nhỏ hơn 100
db.products.find({ price: { $lt: 100 } })

// $lte: Tìm tài liệu nơi trường "quantity" nhỏ hơn hoặc bằng 10
db.inventory.find({ quantity: { $lte: 10 } })

// $in: Tìm tài liệu nơi trường "category" là "books" hoặc "electronics"
db.products.find({ category: { $in: ["books", "electronics"] } })

// $nin: Tìm tài liệu nơi trường "status" không phải là "open" hoặc "pending"
db.tickets.find({ status: { $nin: ["open", "pending"] } })

// $or: Tìm tài liệu nơi trường "age" là 30 hoặc 40
db.users.find({ $or: [{ age: 30 }, { age: 40 }] })

// $nor: Tìm tài liệu nơi trường "age" không phải là 30 hoặc 40
db.users.find({ $nor: [{ age: 30 }, { age: 40 }] })

// $and: Tìm tài liệu nơi trường "status" là "active" và trường "role" là "admin"
db.users.find({ $and: [{ status: "active" }, { role: "admin" }] })

// $not: Tìm tài liệu nơi trường "status" không phải là "inactive"
db.users.find({ status: { $not: { $eq: "inactive" } } })

// $exists: Tìm tài liệu nơi trường "email" tồn tại
db.users.find({ email: { $exists: true } })

// $type: Tìm tài liệu nơi trường "age" là kiểu "number"
db.users.find({ age: { $type: "number" } })

// $regex: Tìm tài liệu nơi trường "name" bắt đầu bằng "Joh"
db.users.find({ name: { $regex: /^Joh/ } })

// $expr: Tìm tài liệu nơi giá trị trường "likes" lớn hơn giá trị trường "dislikes"
// Sử dụng $expr khi bạn cần so sánh các trường trong cùng một tài liệu
db.articles.find({ $expr: { $gt: ["$likes", "$dislikes"] } })

// $size: Tìm tất cả các tài liệu mà mảng "hobbies" có đúng 3 phần tử
db.users.find({ hobbies: { $size: 3 } })

// $all: Tìm tất cả các tài liệu mà mảng "tags" chứa các phần tử "electronics" và "smartphone"
db.products.find({ tags: { $all: ["electronics", "smartphone"] } })

// Kết hợp
db.collection('myCollection').find({
  $or: [
    { age: { $gte: 18, $lte: 30 } }, // tìm tài liệu với tuổi từ 18 đến 30
    { occupation: 'student' } // tìm tài liệu với nghề nghiệp là 'student'
  ],
  $and: [
    { salary: { $gte: 50000 } }, // tìm tài liệu có lương >= 50000
    { location: { $regex: /^New York/ } } // tìm tài liệu với địa điểm bắt đầu bằng 'New York'
  ],
  $not: { company: 'Microsoft' } // tìm tài liệu không có công ty = 'Microsoft'
})

// $: Tìm mục đầu tiên trong mảng "items" có tên là "Widget"
db.orders.find({ "items.name": "Widget" }, { "items.$": 1 })

// $elemMatch: Tìm tất cả các đơn hàng có ít nhất một mục có tên là "Widget" và giá lớn hơn 10
db.orders.find({ items: { $elemMatch: { name: "Widget", price: { $gt: 10 } } } })

// $slice: Tìm tất cả các sản phẩm và trả về chỉ 5 phần tử đầu tiên của mảng "reviews" cho mỗi sản phẩm
db.products.find({}, { reviews: { $slice: 5 } })

o23 Biết cách sử dụng Aggregation Framework để thực hiện các thao tác xử lý dữ liệu phức tạp

db.collection.aggregate([
  // Giai đoạn $match
  {
    $match: {
      age: { $gte: 18 } // tìm các tài liệu có tuổi lớn hơn hoặc bằng 18
    }
  },
  // Giai đoạn $project
  {
    $project: {
      firstName: 1,
      lastName: 1,
      fullName: { $concat: ["$firstName", " ", "$lastName"] }
      // chỉ chọn firstName, lastName và một trường mới fullName nối từ firstName và lastName
    }
  },
  // Giai đoạn $group
  {
    $group: {
      _id: "$gender", // nhóm theo giới tính
      count: { $sum: 1 } // đếm số lượng tài liệu trong mỗi nhóm
    }
  },
  // Giai đoạn $sort
  {
    $sort: {
      count: -1 // sắp xếp theo count theo thứ tự giảm dần
    }
  },
  // Giai đoạn $limit
  {
    $limit: 10 // chỉ trả về 10 kết quả hàng đầu
  }
]);

// Chuyển đổi
// Bạn cũng có thể sử dụng các toán tử có sẵn khác như: $toDate, $toInt, $toBool,...

db.persons.aggregate([
  {
    $project: {
      _id: 0,
      name: 1,
      email: 1,
      birthdate: {
        $convert: {
          input: '$dob.date',
          to: 'date'
        }
      }
    }
  }
]).pretty();

Toán tử $bucket được sử dụng để phân loại các tài liệu thành các nhóm, dựa trên biểu thức và ranh giới đã chỉ định. Ví dụ:

db.persons.aggregate([
  {
    $bucket: {
      groupBy: '$dob.age',
      boundaries: [18, 30, 40, 50, 60, 120],
      output: {
        numPersons: { $sum: 1 },
        averageAge: { $avg: '$dob.age' }
      }
    }
  }
]).pretty();


Trong giai đoạn $projectcủa một pipeline aggregation, bạn có thể sử dụng nhiều toán tử khác ngoài các toán tử toán học. Một số ví dụ bao gồm:

  • Toán tử so sánh: $eq, $ne, $gt, $gte, $lt, $lte
  • Toán tử logic: $and, $or, $not, $nor
  • Toán tử chuỗi: $concat, $substr, $toLower, $toUpper, $trim
  • Toán tử ngày tháng: $dateToString, $dayOfMonth, $dayOfWeek, $year, $month, $hour, $minute, $second, $millisecond
  • Toán tử mảng: $arrayElemAt, $concatArrays, $filter, $in, $slice
  • Toán tử điều kiện: $cond, $ifNull

o24 Biết cách sử dụng Index và Transaction trong MongoDB

Index cũng cho phép bạn thiết lập một số lựa chọn để việc sử dụng Index hiện quả hơn

  • Unique: Tạo một Unique Index để Collection sẽ không chấp nhận việc chèn hoặc cập nhật các Document trong đó giá trị khóa Index khớp với giá trị hiện có trong Index.
  • PartialFilterExpression: Tạo Partial Indexes chỉ tham chiếu tới các một số Document thỏa mãn điều kiện
  • ExpireAfterSeconds: Chỉ định khoảng thời gian mà MongoDB sẽ giữ cho Document tồn tại

Multikey Indexeslà một dạng Index đặc biệt sử dụng cho các trường dạng mảng. Multikey Indexes sẽ tạo các khóa cho từng phần tử trong mảng, từ đó giúp cho việc truy vấn phần tử mảng nhanh hơn.

Text Indexes được sử dụng cho các trường dạng chuỗi. Nếu bạn chỉ tạo index đơn thuần cho các trường dạng chuỗi, lúc này Index chỉ phát huy tác dụng khi bạn tìm theo một chuỗi đầy đủ nhưng sẽ không tốt nếu bạn muốn tìm chuỗi theo từ khóa. Lúc này thì bạn nên sử dụng Text Indexes, MongoDB sẽ tự động cắt chuỗi thành từng từ khóa nhỏ, đồng thời cũng lọc đi các từ khóa vô nghĩa (a, an, of, the,…) và tạo Index cho từng từ khóa. Lúc này khi tìm chuỗi theo từ khóa sẽ nhanh hơn.

Lưu ý là mỗi Collection chỉ có thể có một Text Indexes duy nhất. Do Text Indexes sẽ tốn rất nhiều bộ nhớnên nếu có quá nhiều thì sẽ ảnh hưởng lớn đến hệ thống.

o25 Hiểu về các cơ chế bảo mật và tăng hiệu suất trong MongoDB

Bảo mật

// Chuyển sang cơ sở dữ liệu admin (BẮT BUỘC)
use admin

// Tạo một người dùng mới
db.createUser(
  {
    user: "myuser",
    pwd: "mypassword",
    roles: [
      { role: "read", db: "myproject" }
    ]
  }
);

// Thiết lập một vai trò mới cho người dùng
db.grantRolesToUser(
  "myuser",
  [
    { role: "readWrite", db: "myproject" }
  ]
);

// Mở rộng vai trò của người dùng
db.grantRolesToUser(
  "myuser",
  [
    { role: "dbAdmin", db: "myproject" }
  ]
);

// Xác thực người dùng
db.auth("myuser", "mypassword");

// Tạo một người dùng mới với quyền đọc và ghi vào cơ sở dữ liệu "blog"
// và thiết lập cơ sở dữ liệu xác thực là "blog":
db.createUser({
  user: "myuser",
  pwd: "mypassword",
  roles: [{ role: "readWrite", db: "blog" }],
  authenticationDatabase: "blog"
})

// Xác minh rằng người dùng đã được tạo bằng cách chuyển sang cơ sở dữ liệu xác thực
// và chạy lệnh "show users":
use blog
show users

Hiệu suất

Capped Collection

Capped collections là các Circular Collection có kích cỡ cố định mà theo sau thứ tự chèn để làm tăng cao hiệu suất của các hoạt động create, read và delete. Với Circular, nó nghĩa là khi kích cỡ cố định được cấp phát hết cho Collection, thì nó sẽ bắt đầu xóa Document cũ nhất trong Collection đó mà không cần cung cấp bất kỳ lệnh tường minh nào.

Capped Collection giới hạn các hoạt động cập nhật tới Document nếu các cập nhật đó làm tăng kích cỡ của Document. Khi Capped Collection lưu giữ các Document theo trật tự của Disk Storage, nó bảo đảm rằng kích cỡ tài liệu không tăng hơn kích cỡ được cấp phát trên Disk. Capped Collection là tốt nhất để lưu giữ thông tin log, cache data, …

Replica Sets

Replica Sets trong MongoDB là một nhóm các instancecủa MongoDB duy trì cùng một bộ dữ liệu. Các replica set cung cấp tính dự phòng và tính sẵn sàng cao và là cơ sở để triển khai nhập xuất dữ liệu khi cần thiết.

Sharding

Sharding là một tiến trình lưu giữ các bản ghi dữ liệu qua nhiều thiết bị và nó là một phương pháp của MongoDB để đáp ứng yêu cầu về sự gia tăng dữ liệu. Khi kích cỡ của dữ liệu tăng lên, một thiết bị đơn không thể đủ để lưu giữ dữ liệu. Sharding giải quyết vấn đề này với việc mở rộng phạm vi theo bề ngang (horizontal scaling). Với Sharding, bạn bổ sung thêm nhiều thiết bị để hỗ trợ cho việc gia tăng dữ liệu và các yêu cầu của các hoạt động đọc và ghi.

o26 Biết cách đọc dữ liệu từ các file.

# Ví dụ về đọc từ một tệp
with open('Example1.txt', 'r') as file_object:
    file_stuff = file_object.read()
print(file_stuff)

# Đọc các dòng từ một tệp
with open('Example1.txt', 'r') as file_object:
    file_stuff = file_object.readlines()
for line in file_stuff:
    print(line)

# Đọc một dòng tại một thời điểm từ một tệp
with open('Example1.txt', 'r') as file_object:
    file_stuff = file_object.readline()
    print(file_stuff)
    file_stuff = file_object.readline()
    print(file_stuff)

# Đọc một số lượng ký tự cụ thể từ một tệp
with open('Example1.txt', 'r') as file_object:
    file_stuff = file_object.read(4)  # Đọc 4 ký tự đầu tiên
    print(file_stuff)
    file_stuff = file_object.read(16)  # Đọc 16 ký tự tiếp theo
    print(file_stuff)
    file_stuff = file_object.read(5)  # Đọc 5 ký tự tiếp theo
    print(file_stuff)

# Ghi vào một tệp
with open('Example2.txt', 'w') as file_object:
    file_object.write('Hello, world!\n')  # Ghi chuỗi vào tệp
    file_object.write('This is a new line.\n')  # Ghi chuỗi mới vào dòng mới

# Ghi thêm vào một tệp
with open('Example2.txt', 'a') as file_object:
    file_object.write('This is a third line.\n')  # Ghi thêm chuỗi vào cuối tệp

o27 Biết cách xử lý dữ liệu dạng JSON

import json

# Link tới tệp JSON trên Google Drive
# https://drive.google.com/file/d/17IbjlB_f1xVAqBd8lLS6BIVGnmmPRTJp/view

# Tạo một từ điển
person = {
    "name": "John",
    "age": 30,
    "city": "New York"
}

# Chuyển đổi từ điển thành chuỗi JSON
person_json = json.dumps(person)

# In ra chuỗi JSON
print(person_json)

# Chuyển đổi chuỗi JSON thành từ điển
person_dict = json.loads(person_json)

# In ra từ điển
print(person_dict)

# Lưu từ điển vào tệp JSON
with open("person.json", "w") as f:
    json.dump(person_dict, f)

# Đọc từ điển từ tệp JSON
with open("person.json", "r") as f:
    person_from_file = json.load(f)

# In ra từ điển được tải từ tệp
print(person_from_file)

# Truy cập key 'name' của từ điển
print(person_from_file['name'])

# Truy cập key 'age' của từ điển
print(person_from_file['age'])

# Truy cập key 'city' của từ điển
print(person_from_file['city'])

o28 Biết cách sử dụng Regex để trích xuất dữ liệu từ chuỗi.

import re

# Tìm kiếm một mẫu trong một chuỗi
text = "The quick brown fox jumps over the lazy dog"
pattern = "brown"
match = re.search(pattern, text)
if match:
    print(f"Found '{pattern}' in '{text}' at position {match.start()}")
else:
    print(f"'{pattern}' not found in '{text}'")

# Tìm tất cả các xuất hiện của một mẫu trong một chuỗi
text = "The quick brown fox jumps over the lazy dog"
pattern = "the"
matches = re.findall(pattern, text, re.IGNORECASE)
if matches:
    print(f"Found {len(matches)} occurrences of '{pattern}' in '{text}'")
else:
    print(f"'{pattern}' not found in '{text}'")

# Thay thế tất cả các xuất hiện của một mẫu trong một chuỗi
text = "The quick brown fox jumps over the lazy dog"
pattern = "the"
replacement = "THE"
new_text = re.sub(pattern, replacement, text, flags=re.IGNORECASE)
print(f"Original text: '{text}'")
print(f"New text: '{new_text}'")

o29 Biết cách sử dụng Scrapy để thu thập dữ liệu từ các web tĩnh

# Tạo một dự án Scrapy mới có tên là "worldometers".
scrapy startproject worldometers

# Tạo một spider mới có tên là "countries" để trích xuất dữ liệu từ trang web worldometers.info.
scrapy genspider countries www.worldometers.info/world-population/population-by-country

# Chạy spider "countries" trong dự án để trích xuất dữ liệu.
scrapy crawl countries

# Chạy spider "countries" và lưu kết quả vào tệp population_dataset.csv.
scrapy crawl countries -o population_dataset.csv

# Bắt đầu Scrapy Shell cho URL được cung cấp để thử nghiệm và phát triển spiders.
scrapy shell [url]

o30 Hiểu rõ về CSS Selector và xPath để lấy dữ liệu

# Chọn phần tử div với id 'main'
//div[@id='main']

# Chọn phần tử h1 trong phần tử div có id 'main'
//div[@id='main']/h1

# Chọn tất cả các phần tử a trong các phần tử li nằm dưới div có id 'main'
//div[@id='main']//li/a

# Chọn phần tử div với id 'main'
div#main

# Chọn phần tử h1 trong phần tử div có id 'main'
div#main h1

# Chọn tất cả các phần tử a trong các phần tử li nằm dưới div có id 'main'
div#main li a

# Chọn phần tử div có class 'container'
//div[@class='container']

# Chọn phần tử h2 trong phần tử div có class 'container'
//div[@class='container']/h2

# Chọn tất cả các phần tử li nằm trong phần tử div có class 'container'
//div[@class='container']//li

# Chọn phần tử div có class 'container'
div.container

# Chọn phần tử h2 trong phần tử div có class 'container'
div.container h2

# Chọn tất cả các phần tử li nằm trong phần tử div có class 'container'
div.container li

# Chọn phần tử td thứ hai trong phần tử tr đầu tiên
//table/tbody/tr[1]/td[2]

# Chọn phần tử td thứ ba trong tất cả các phần tử tr trong tbody của bảng
//table/tbody/tr/td[3]

# Chọn phần tử td thứ hai trong phần tử tr đầu tiên
table tbody tr:first-child td:nth-child(2)

# Chọn phần tử td thứ ba trong tất cả các phần tử tr trong tbody của bảng
table tbody tr td:nth-child(3)

o31 Biết cách sử dụng Scrapy và Splash để thu thập dữ liệu từ các web động

class CoinSpider(scrapy.Spider):

    name = "coin"

    allowed_domains = ["web.archive.org"]

    script = '''
        function main(splash, args)
            url = args.url
            assert(splash:go(url))
            assert(splash:wait(3))
            rur_tab = assert(splash:select_all(".filterPanelItem___2z5Gb"))
            rur_tab[1]:mouse_click()
            assert(splash:wait(3))
            splash:set_viewport_full()
            return splash:html()
        end
    '''

    def start_requests(self):
        yield SplashRequest(url="https://web.archive.org/web/20200116052415/https://www.livecoin.net/en/", callback=self.parse, endpoint="execute", args={
            'lua_source': self.script
        })

    def parse(self, response):
        # inspect_response(response, self)
        for currency in response.css(".ReactVirtualized__Table .tableRow___3EtiS"):
            yield {
                'currency pair': currency.css("div:nth-child(1) div::text").get(),
                'volume(24h)': currency.css("div:nth-child(2) span::text").get()
            }

o32 Nắm được các Scraping APIs

class CountriesSpider(scrapy.Spider):

    name = "countries"

    allowed_domains = ["www.worldometers.info"]

    start_urls = ["https://www.worldometers.info/world-population/population-by-country/"]

    def parse(self, response):
        countries = response.css("td a")

        for country in countries:
            name = country.css("::text").get()
            link = country.css("::attr(href)").get()
            yield response.follow(url=link, callback=self.parse_country, meta={'country_name': name})

    def parse_country(self, response):
        name = response.request.meta['country_name']
        rows = response.css("table.table.table-striped.table-bordered.table-hover.table-condensed.table-list:nth-child(1) tbody tr")

        for row in rows:
            year = row.css("td:nth-child(1)::text").get()
            population = row.css("td:nth-child(2) strong::text").get()
            yield {
                'country_name': name,
                'year': year,
                'population': population
            }

Comments

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Mục Lục

Index