Mô hình hóa cấu trúc cơ sở dữ liệu cho nhiều loại người dùng và thông tin liên hệ của họ


10

Tôi đang thiết kế một cơ sở dữ liệu sẽ lưu trữ người dùng thuộc các loại khác nhau. Chủ yếu (nhưng không độc quyền) họ sẽ là Diễn viên, Giám đốc và Nhà văn. Hiện tại chỉ có bốn loại người dùng có liên quan. Có một cơ hội bên ngoài rằng con số này có thể tăng lên, nhưng xác suất là thấp - và trong trường hợp như vậy sẽ là một con số rất nhỏ.

Kế hoạch này là phải có một usersbảng có trách nhiệm khá nhiều chỉ để đăng nhập vào các trang web ( name, emailpasswordcột cộng với một hoặc hai người khác chẳng hạn như liệu họ đã được phê duyệt, và updated_at), và bảng bổ sung cho mỗi loại sử dụng tương ứng mà mỗi có bộ cột độc đáo của riêng họ. Chẳng hạn, chỉ các diễn viên mới có cột dân tộc, chỉ Giám đốc mới có cột sinh học và chỉ Nhà văn mới cần cung cấp vị trí của họ. Tuy nhiên, vì tôi chưa quản lý cơ sở dữ liệu về sự phức tạp này trước đây, tôi tự hỏi làm thế nào để tổ chức một vài khía cạnh:

Thứ nhất, người dùng có thể là bất kỳ một, hoặc bất kỳ sự kết hợp nào, thuộc các loại trên. Vì vậy, tôi hiểu rằng tôi sẽ cần một cái gì đó như (ví dụ) một director_userbảng có director_iduser_idcác cột. Điều này sau đó có đủ để có thể lọc tất cả người dùng theo loại vai trò hay không?

Thứ hai, hầu hết người dùng sẽ tùy chọn hồ sơ twitter và số điện thoại. Và tất cả các diễn viên sẽ phải bao gồm ít nhất một URL cho bất kỳ hồ sơ diễn viên trực tuyến nào khác của họ; hiện tại có ba cái mà họ có thể bao gồm, nhưng con số này có thể tăng lên. Tôi có đúng không khi cho rằng một bảng riêng cho từng cấu hình / phương thức liên hệ có thể là một cách tối ưu để sắp xếp dữ liệu?

Câu trả lời:


13

Theo cách giải thích của tôi về mô tả của bạn về bối cảnh kinh doanh mà bạn quan tâm, bạn đang xử lý một cấu trúc siêu kiểu 1 trong đó (a) Diễn viên , Giám đốcNhà văn là các kiểu con thực thể của (b) Person , siêu thực thể của họ và (c) phân nhóm nói không loại trừ lẫn nhau.

Theo cách này, nếu bạn quan tâm đến việc xây dựng cơ sở dữ liệu quan hệ phản ánh chính xác kịch bản như vậy và do đó hy vọng rằng nó hoạt động như vậy, thì việc làm rõ nhận xét sau của bạn khá quan trọng đối với các điểm trước đó, bởi vì chúng có ý nghĩa tại cả (1) khái niệm và (2) mức độ biểu diễn logic của cơ sở dữ liệu được đề cập:

  • [V]] bảng bổ sung cho từng loại người dùng tương ứng mà mỗi loại có bộ cột duy nhất của riêng họ.

  • [V]] chỉ có bốn loại người dùng có liên quan. Có một cơ hội bên ngoài rằng con số này có thể tăng lên, nhưng xác suất là thấp - và trong trường hợp như vậy sẽ là một con số rất nhỏ.

Tôi sẽ giải thích tất cả các khía cạnh đó và một số yếu tố quan trọng khác trong các phần dưới đây.

Quy tắc kinh doanh

Trước tiên, để xác định lược đồ khái niệm tương ứng, có thể sử dụng lược đồ tương ứng để bạn có thể điều chỉnh nó để đảm bảo rằng nó đáp ứng các yêu cầu thông tin chính xác của Wap , tôi đã xây dựng một số quy tắc kinh doanh có tầm quan trọng đặc biệt:

  • Một Người có thể thực hiện Vai trò 2 hoặc 3 (tức là một đối với tất cả) . Nói cách khác, một người có thể
    • một diễn viên
    • một giám đốc
    • một nhà văn .
  • Một người có thể đăng nhập thông qua UserProfile 0 hoặc 1 .
  • Một diễn viên cung cấp một hoặc hai hoặc ba URL 3 .
  • Một diễn viên được nhóm bởi một dân tộc .
  • Một nhóm dân tộc không có một hoặc nhiều diễn viên .
  • Một Nhà văn dựa trên một Địa điểm .
  • Một Location là cơ sở của zero-một-hay-hơn Writers .

Sơ đồ IDEF1X tiếp xúc

Sau đó, tôi đã tạo sơ đồ IDEF1X 4 được hiển thị trong Hình 1 , nhóm này bao gồm tất cả các công thức ở trên cùng với các quy tắc khác xuất hiện thích hợp:

Hình 1 - Sơ đồ IDEF1X cho vai trò người và chi tiết liên lạc trong điện ảnh

Như đã trình bày, siêu kiểu Person (i) có hộp riêng, (ii) sở hữu các thuộc tính hoặc thuộc tính áp dụng cho tất cả các kiểu con và (iii) trình bày các dòng kết nối nó với các hộp của mỗi kiểu con.

Đổi lại, mọi kiểu con (a) xuất hiện trong hộp chuyên dụng của riêng nó và (b) giữ độc quyền các thuộc tính áp dụng của nó. KEY PRIMARY của supertype, PersonId , di chuyển 5 đến các kiểu con với tên vai trò lần lượt là 6 ActorId , DirectorIdWriterId .

Ngoài ra, tôi đã tránh ghép Người với loại thực thể UserProfile , cho phép tách tất cả các hàm ý, liên kết hoặc mối quan hệ theo ngữ cảnh của họ, v.v. Thuộc tính PersonId đã di chuyển sang UserProfile với tên vai trò UserId .

Bạn nêu trong cơ quan câu hỏi rằng

Và tất cả các diễn viên sẽ phải bao gồm ít nhất một URL cho bất kỳ hồ sơ diễn viên trực tuyến nào khác của họ; hiện tại có ba cái mà họ có thể bao gồm, nhưng con số này có thể tăng lên.

Vì vậy, URL là một loại thực thể theo đúng nghĩa của nó và được liên kết trực tiếp với phân nhóm Diễn viên theo trích dẫn này.

Và, trong các bình luận , bạn xác định rằng

[Mạnh] một diễn viên sẽ có một headshot (ảnh), trong khi một nhà văn sẽ không [Bắn]

Sau đó, trong số các tính năng khác, tôi đã bao gồm Headshot như một thuộc tính của loại thực thể Actor .

Đối với các loại thực thể Dân tộcĐịa điểm , tất nhiên họ có thể yêu cầu các tổ chức phức tạp hơn (ví dụ: Diễn viên có thể thuộc một, hai hoặc nhiều nhóm dân tộc khác nhau theo tỷ lệ riêng biệt và Nhà văn có thể dựa trên một địa điểm cần ghi âm quốc gia, khu vực hành chính, quận, v.v.) nhưng có vẻ như nhu cầu của bối cảnh kinh doanh của bạn được bao phủ thành công với các cấu trúc ở đây được mô hình hóa.

Đương nhiên, bạn có thể thực hiện nhiều điều chỉnh khi cần thiết.

Thiết kế logic SQL-DDL minh họa

Do đó, dựa trên sơ đồ IDEF1X được hiển thị và mô tả ở trên, tôi đã viết bố cục DDL logic được hiển thị như sau (Tôi đã cung cấp các ghi chú giải thích một số đặc điểm mà tôi đánh giá là đặc biệt quan trọng đối với các bảng, cột và ràng buộc khai báo):

-- You should determine which are the most fitting 
-- data types and sizes for all your table columns 
-- depending on your business context characteristics.

-- Also, you should make accurate tests to define the 
-- most convenient INDEX strategies based on the exact 
-- data manipulation tendencies of your business needs.

-- As one would expect, you are free to utilize 
-- your preferred (or required) naming conventions. 

CREATE TABLE Person ( -- Represents the supertype.
    PersonId       INT      NOT NULL,
    FirstName      CHAR(30) NOT NULL,
    LastName       CHAR(30) NOT NULL,
    BirthDate      DATE     NOT NULL,
    GenderCode     CHAR(3)  NOT NULL,
    TwitterProfile CHAR(30) NOT NULL,
    PhoneNumber    CHAR(30) NOT NULL,
    EmailAddress   CHAR(30) NOT NULL,  
    CreatedDateTime DATETIME NOT NULL,
    --
    CONSTRAINT Person_PK  PRIMARY KEY (PersonId),
    CONSTRAINT Person_AK1 UNIQUE ( -- Composite ALTERNATE KEY.
        FirstName,
        LastName,
        GenderCode,
        BirthDate
    ),
    CONSTRAINT Person_AK2 UNIQUE (TwitterProfile), -- ALTERNATE KEY.
    CONSTRAINT Person_AK3 UNIQUE (EmailAddress)    -- ALTERNATE KEY.
);

CREATE TABLE Ethnicity ( -- Its rows will serve a “look-up” purpose.
    EthnicityId     INT      NOT NULL,
    Name            CHAR(30) NOT NULL,  
    Description     CHAR(30) NOT NULL,
    CreatedDateTime DATETIME NOT NULL,
    -- 
    CONSTRAINT Ethnicity_PK PRIMARY KEY (EthnicityId),
    CONSTRAINT Ethnicity_AK UNIQUE      (Description)   
);

CREATE TABLE Actor ( -- Stands for one of the subtypes.
    ActorId         INT      NOT NULL, -- Must be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
    Headshot        CHAR(30) NOT NULL, -- May, e.g., contain a URL indicating the path where the photo file is actually stored. 
    EthnicityId     INT      NOT NULL,
    CreatedDateTime DATETIME NOT NULL,
    -- 
    CONSTRAINT Actor_PK            PRIMARY KEY (ActorId),
    CONSTRAINT ActorToPerson_PK    FOREIGN KEY (ActorId)
        REFERENCES Person (PersonId),
    CONSTRAINT ActorToEthnicity_PK FOREIGN KEY (EthnicityId)
        REFERENCES Ethnicity (EthnicityId)   
);

CREATE TABLE Director ( -- Denotes one of the subtypes
    DirectorId      INT       NOT NULL, -- Must be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
    Bio             CHAR(120) NOT NULL,  
    Etcetera        CHAR(30)  NOT NULL,
    CreatedDateTime DATETIME  NOT NULL,
    -- 
    CONSTRAINT Director_PK         PRIMARY KEY (DirectorId),
    CONSTRAINT DirectorToPerson_PK FOREIGN KEY (DirectorId)
        REFERENCES Person (PersonId)   
);

CREATE TABLE Country (
    CountryCode     CHAR(2)  NOT NULL,
    Name            CHAR(30) NOT NULL,  
    CreatedDateTime DATETIME NOT NULL,
    -- 
    CONSTRAINT Country_PK PRIMARY KEY (CountryCode),
    CONSTRAINT Country_AK UNIQUE      (Name)   
);

CREATE TABLE Location ( -- Its rows will serve a “look-up” purpose.
    CountryCode     CHAR(2)  NOT NULL,
    LocationCode    CHAR(3)  NOT NULL,
    Name            CHAR(30) NOT NULL,  
    CreatedDateTime DATETIME NOT NULL,
    -- 
    CONSTRAINT Location_PK PRIMARY KEY (CountryCode, LocationCode),
    CONSTRAINT Location_AK UNIQUE      (CountryCode, Name)   
);

CREATE TABLE Writer ( -- Represents one of the subtypes.
    WriterId        INT      NOT NULL, -- Must be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
    CountryCode     CHAR(2)  NOT NULL,
    LocationCode    CHAR(3)  NOT NULL,
    CreatedDateTime DATETIME NOT NULL,
    -- 
    CONSTRAINT Writer_PK           PRIMARY KEY (WriterId),
    CONSTRAINT WriterToPerson_PK   FOREIGN KEY (WriterId)
        REFERENCES Person (PersonId),
    CONSTRAINT WriterToLocation_PK FOREIGN KEY (CountryCode, LocationCode)
        REFERENCES Location (CountryCode, LocationCode)  
);

CREATE TABLE UserProfile (
    UserId          INT      NOT NULL, -- Must be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
    UserName        CHAR(30) NOT NULL,
    Etcetera        CHAR(30) NOT NULL,
    CreatedDateTime DATETIME NOT NULL,
    -- 
    CONSTRAINT UserProfile_PK PRIMARY KEY (UserId),
    CONSTRAINT UserProfile_AK UNIQUE      (UserName), -- ALTERNATE KEY.
    CONSTRAINT UserProfileToPerson_PK FOREIGN KEY (UserId)
        REFERENCES Person (PersonId)    
);

CREATE TABLE URL (
    ActorId       INT      NOT NULL,
    Address       CHAR(90) NOT NULL,
    Etcetera      CHAR(30) NOT NULL,
    AddedDateTime DATETIME NOT NULL,
    -- 
    CONSTRAINT URL_PK        PRIMARY KEY (ActorId, Address), -- Composite PRIMARY KEY.
    CONSTRAINT URLtoActor_FK FOREIGN KEY (ActorId)
        REFERENCES Actor (ActorId)
);

Do đó, (1) mọi khía cạnh số ít của bố cục logic ở trên đều mang một ý nghĩa rất chính xác từ (2) một đặc điểm riêng của môi trường kinh doanh theo thỏa thuận 7 lợi ích với tinh thần của khung quan hệ của Tiến sĩ Edgar Frank Codd -, bởi vì:

  • Mỗi bảng cơ sở đại diện cho một loại thực thể riêng.
  • Mỗi cột là viết tắt của một thuộc tính duy nhất của loại thực thể tương ứng.
  • Một loại dữ liệu cụ thể được cố định cho từng cột để đảm bảo rằng tất cả các giá trị mà nó chứa thuộc về một tập hợp cụ thể và được phân tách chính xác a, có thể là INT, DATETIME, CHAR, v.v. (và chúng tôi hy vọng rằng cuối cùng MySQL sẽ kết hợp DOMAIN hỗ trợ trong phiên bản tương lai gần).
  • Nhiều ràng buộc được cấu hình (khai báo) để đảm bảo rằng các xác nhận dưới dạng hàng được giữ lại trong tất cả các bảng tuân thủ các quy tắc kinh doanh được xác định ở cấp độ khái niệm.
  • Mỗi hàng có nghĩa là truyền đạt ngữ nghĩa được xác định rõ, ví dụ: một Personhàng được đọc

    Người được xác định bởi PersonId rđược gọi bởi FirstName svà LastName t, được sinh ra trên BirthDate u, có Giới tính v, các tweet trên TwitterProfile w, được truy cập qua PhoneNumber x, được liên hệ qua EmailAddress yvà được đăng ký trên createdDateTimez .

Việc có bố cục như thế này rất thuận lợi, vì bạn có thể rút ra các bảng mới (ví dụ: các thao tác CHỌN thu thập các cột TỪ nhiều bảng với sự trợ giúp của mệnh đề THAM GIA) mà sự thành công của Wapin cũng mang một ý nghĩa rất chính xác (xem phần mang tên xem Lượt xem dưới đây).

Chúng ta sẽ đề cập rằng, với cấu hình này, (i) một hàng đại diện cho một thể hiện của kiểu con được xác định bởi (ii) cùng một giá trị PRIMARY KEY để phân biệt hàng biểu thị sự xuất hiện của siêu kiểu bổ sung. Vì vậy, nó là nhiều hơn cơ hội để lưu ý rằng

  • (a) đính kèm một cột bổ sung để giữ các thay thế được tạo bởi hệ thống và được gán bởi hệ thống 8 đến (b) các bảng đứng cho các kiểu con là (c) hoàn toàn không cần thiết .

Với thiết kế logic này, nếu các kiểu con mới được xác định là có liên quan trong bối cảnh kinh doanh của bạn, bạn sẽ phải khai báo một bảng cơ sở mới, nhưng điều đó cũng xảy ra khi các loại thực thể khác được coi là có ý nghĩa, vì vậy, tình huống sẽ xảy ra Thực tế, bình thường.

Lượt xem

Để tải xuống Fetch, ví dụ, tất cả thông tin tương ứng với Diễn viên , Giám đốc hoặc Nhà văn , bạn có thể khai báo một số chế độ xem (ví dụ: bảng có nguồn gốc hoặc có thể biểu thị) để bạn có thể CHỌN trực tiếp từ một tài nguyên mà không cần phải viết liên quan đến THAM GIA mọi lúc; ví dụ, với VIEW được khai báo bên dưới, bạn có thể có được thông tin Diễn viên đầy đủ của hoàng tử :

--
CREATE VIEW FullActor AS

    SELECT P.FirstName,
           P.Lastname,
           P.BirthDate,
           P.GenderCode,
           P.TwitterProfile,
           P.PhoneNumber,
           P.EmailAddress,
           A.Headshot,
           E.Name AS Ethnicity
         FROM Person P
         JOIN Actor A
           ON A.ActorId     = P.PersonId
         JOIN Ethnicity E
           ON E.EthnicityId = A.EthnicityId;
--

Tất nhiên, bạn có thể làm theo một cách tiếp cận tương tự để lấy thông tin về Giám đốcNhà văn đầy đủ của hoàng tử :

--
CREATE VIEW FullDirector AS

    SELECT P.FirstName,
           P.Lastname,
           P.BirthDate,
           P.GenderCode,
           P.TwitterProfile,
           P.PhoneNumber,
           P.EmailAddress,
           D.Bio,
           D.Etcetera
         FROM Person P
         JOIN Director D
           ON D.DirectorId = P.PersonId; 

--
CREATE VIEW FullWriter AS

    SELECT P.FirstName,
           P.Lastname,
           P.BirthDate,
           P.GenderCode,
           P.TwitterProfile,
           P.PhoneNumber,
           P.EmailAddress,
           L.Name AS Location,
           C.Name AS Country
         FROM Person P
         JOIN Writer W
           ON W.WriterId     = P.PersonId
         JOIN Country C
           ON C.CountryCode  = W.CountryCode
         JOIN Location L
           ON L.LocationCode = W.LocationCode;   
--

Tôi đã đăng tất cả các câu lệnh DDL và các khung nhìn DML ở đây đã thảo luận trong SQL Fiddle này chạy trên MySQL 5.6 để bạn có thể xem và kiểm tra chúng trong hành động.


Chú thích

1 Trong một số kỹ thuật mô hình hóa khái niệm, các hiệp hội siêu kiểu con được gọi là mối quan hệ lớp siêu lớp .

2 Mặc dù bạn đề cập rằng trên thực tế tồn tại nhiều Vai trò hơn mà một Người có thể thực hiện, nhưng ba người bạn tiết lộ là đủ tốt để thảo luận về kịch bản phơi bày một số phân nhánh quan trọng .

3 Nhưng, như bạn đã lưu ý, trong tương lai, một Diễn viên cuối cùng có thể cung cấp một-nhiều URL .

4 Định nghĩa tích hợp cho mô hình hóa thông tin ( IDEF1X ) là một kỹ thuật mô hình rất được khuyến khích, được thành lập như một tiêu chuẩn vào tháng 12 năm 1993 bởi Viện Tiêu chuẩn và Công nghệ Quốc gia Hoa Kỳ (NIST). Nó dựa trên (a) các công trình lý thuyết ban đầu được tác giả bởi người khởi tạo duy nhất của mô hình dữ liệu quan hệ, tức là, Tiến sĩ EF Codd; trên (b) quan điểm về mối quan hệ thực thể , được phát triển bởi Tiến sĩ PP Chen ; và cũng trên (c) Kỹ thuật thiết kế cơ sở dữ liệu logic, được tạo bởi Robert G. Brown.

5 Tiêu chuẩn IDEF1X định nghĩa di chuyển khóa là quy trình Mô hình hóa việc đặt khóa chính của một thực thể cha mẹ hoặc chung [tức là một siêu kiểu] trong thực thể con hoặc thể loại của nó [tức là một kiểu con] như là một khóa ngoại.

6 Trong IDEF1X, tên vai trò là nhãn đặc biệt được gán cho thuộc tính FK để thể hiện ý nghĩa mà nó giữ trong phạm vi của loại thực thể tương ứng.

7 Ngoại trừ, một cách tự nhiên, đối với các thuộc tính khái niệm giả định (và các cột logic) Director.EtceteraUserProfile.Etcetera , chỉ là các trình giữ chỗ mà tôi đã sử dụng để thể hiện tính khả thi của việc thêm nhiều thuộc tính (và cột) áp dụng cho loại thực thể khái niệm tương ứng (và bảng logic).

8 Ví dụ, nối thêm một cột bổ sung với thuộc tính AUTO_INCREMENT vào bảng cơ sở dữ liệu, chạy chạy trên MySQL.


2

Bạn nên chia phần này thành các bảng như thế này (chỉ hiển thị các cột cần thiết để trình bày khái niệm, không nhất thiết là tất cả các cột):

Users
ID   Username   FirstName   LastName   PasswordHash ...
 1   'Joe1'      'Joe'      'Smith'
 2   'Freddy'    'Fred'     'Jones'

Roles
ID   RoleType ....
 1   'Writer'
 2   'Director'
 3   'Actor'

User_Roles
User_ID   Role_ID ...
1         1
1         2
2         2
2         3

Điều này cung cấp cho bạn một bảng đầy đủ người dùng với tất cả các cột người dùng khác nhau, bảng vai trò và bảng liên kết để kết nối hai người lại với nhau.

Bạn có thể thấy Joe1 vừa là nhà văn vừa là giám đốc bởi các mục trong User_Roles. Và Freddy vừa là đạo diễn vừa là diễn viên.

Điều này cũng cho phép bạn thêm nhiều vai trò sau này mà không thay đổi hệ thống. Chỉ cần chèn các bản ghi cho Nhà sản xuất hoặc Trình chỉnh sửa hoặc bất cứ điều gì xuống dòng.

Vì vậy, để tìm tất cả tên người dùng của các diễn viên, bạn có một vài lựa chọn:

 Select Distinct Username
   from Users
  Where User_ID in (select User_ID from User_Roles where Role_ID = 3)

Hoặc nếu bạn không biết số vai trò_ID, thì:

 Select Distinct Username
   from Users
  Where User_ID in (Select User_ID from User_Roles where Role_ID = 
                       (Select ID from Roles where RoleType = 'Actor')
                   )

Hoặc bạn cũng có thể làm điều này:

select u.Username, r.RoleType
  from Users u
 inner join User_Roles ur on ur.User_ID = u.ID
 inner join Roles r on r.ID = ur.Role_ID
 where r.RoleType = 'Actor'

(Trong phiên bản này, bạn cũng có thể sử dụng Where r.Role_ID = 3để có kết quả tương tự.)

Nhưng tôi sẽ sử dụng truy vấn đầu tiên và bất kỳ mệnh đề WHERE nào tôi biết. Nói chung, trong một hệ thống lớn, biết rằng Role_ID sẽ chạy nhanh hơn văn bản, vì dữ liệu số là "dễ dàng" hơn và hiệu quả hơn đối với hầu hết các công cụ SQL để xử lý các chỉ mục.

Đối với phương pháp liên lạc hoặc các bức ảnh hoặc bất cứ điều gì, tôi sẽ thực hiện chúng theo cách tương tự:

Attributes
ID    MethodText    ...
1     'TwitterID'
2     'URL'
3     'CellPhone'
4     'Email'
5     'PictureLink'

Role_Attributes
Role_ID  Attribute_ID isRequired
3        5             1
3        4             1
3        3             0

User_Attributes
User_ID  Attribute_ID  AttributeData
1         4            'Joe@Example.com'
1         1            '@joe'
1         3            '555-555-5555'
1         5            'www.example.com/pics/myFace.png'

...và như thế. Chúng sẽ liên kết theo cách tương tự như người dùng với vai trò.

Điều này cho thấy mỗi vai trò có 0 đến nhiều thuộc tính, có thể là tùy chọn. Sau đó, mỗi người dùng có 0 đến nhiều thuộc tính, với dữ liệu cho các thuộc tính đó.

Điều này cho phép bạn thêm các thuộc tính mới khi thời gian trôi qua mà không cần viết lại bất kỳ mã nào; chỉ cần cập nhật các thuộc tính và vai trò bảng để phù hợp với quy tắc mới của bạn. Nó cũng cho phép bạn chia sẻ các thuộc tính giữa các vai trò mà không cần nhập lại cùng một dữ liệu cho mỗi người dùng. Nếu hai vai trò yêu cầu ảnh, thì họ chỉ phải tải lên 1 pic để thực hiện yêu cầu đó.


Aha, tôi nghĩ điều đó có ý nghĩa ở một khía cạnh nào đó ... nhưng tôi không rõ lắm về cách thức - ví dụ - tôi liệt kê tất cả các diễn viên cùng với, nói, Tên người dùng của họ (giả sử rằng dữ liệu diễn viên-y được lưu trữ trong một bảng riêng).
phán đoán

Xem các chỉnh sửa của tôi; Tôi đã thêm ví dụ truy vấn.
CaM

Điều đó vô cùng hữu ích, cảm ơn. Tôi nghĩ rằng tôi có thể không hoàn toàn rõ ràng trong câu hỏi của tôi mặc dù - xin lỗi. Tôi nên nói rõ hơn rằng các bảng cho từng loại (Diễn viên, Giám đốc, v.v.) sẽ có bộ thuộc tính duy nhất của riêng chúng chỉ liên quan đến loại người dùng đó. Ví dụ: một diễn viên sẽ có một headshot (ảnh), trong khi một Nhà văn thì không. Xin lỗi một lần nữa vì không rõ ràng hơn về điều này.
phán đoán

Các phương pháp liên lạc có vẻ là một giải pháp tuyệt vời.
phán đoán

1
Thay đổi điều đó thành thuộc tính, để đáp ứng các yêu cầu cho ảnh, v.v ... Bây giờ nên phù hợp hơn.
CaM
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.