在我的代码中,我通过创建从一个基本类“ ProjectAttribute”继承的5个类来区分“描述”项目的5种类型的属性。一个项目可以具有每种属性类型的0到x(因此在SQL中是多对多)。
这里是一些伪代码:
<main class="main aktualitasu_saraksta_konteineris" role="main">
<?php
$args = array(
'post_type' => 'post',
'posts_per_page' => -1,
'group_by' => 'date',
'order' => 'DESC',
'ignore_sticky_posts' => 1
);
$query = new WP_Query($args);
?>
<?php if ($query->have_posts()) : while ($query->have_posts()) : $query->the_post(); ?>
<?php get_template_part( 'parts/loop', 'news' ); ?>
<?php endwhile; endif; wp_reset_postdata();?>
</main>
每个此类都有一个不同的数据集,我想将它们存储在SQL数据库中。但是,为相同的类创建5个表会让人感到不对,这将导致另外5个链接表将其链接到另一个表(多对多)。最后,我想到了2种不同的想法
想法1
我创建了5个表以及5个链接表,将其链接到“项目”表。
感觉不对,因为每个属性表将包含大约20-30个条目,并且我必须查询5个不同的链接表才能解决此“混乱”。
想法2
我创建了一个名为“ ProjectAttrbiutes”的表,并为每种属性类型添加了另外一列。即“ IsSWAttribute”,“ IsHardwareAttrobite”。此外,我仅添加一个链接表。
听起来更好,但建议将原始数据结构缩减为一张表吗?
另一方面,我最终只需要查询一个链接表。
希望您能为我指明正确的方向。
答案 0 :(得分:0)
我将为此使用4个表。
包含项目的表。
包含属性的表。
包含属性类型的表。
链接项目和属性的表
[Project]-> [ProjectAttribute] <-[Attribute]-> [attributeType]
对于属性类型,在MySQL和PgSQL中有一些不错的类型,即枚举类型。在MS SQL中,您可以建立一个常规表。
MS SQL Server 2017架构设置:
CREATE TABLE project
(
id INT IDENTITY PRIMARY KEY NOT NULL,
name VARCHAR(255)
);
CREATE TABLE attributeType
(
id INT IDENTITY PRIMARY KEY NOT NULL,
name VARCHAR(255)
);
CREATE TABLE attribute
(
id INT IDENTITY PRIMARY KEY NOT NULL,
title VARCHAR(255),
type_id INT,
CONSTRAINT FK_attributeType FOREIGN KEY (type_id)
REFERENCES attributeType(id)
);
CREATE TABLE ProjectAttribute
(
project_id INT NOT NULL,
attribute_id INT NOT NULL,
CONSTRAINT FK_project FOREIGN KEY (project_id)
REFERENCES project(id),
CONSTRAINT FK_attribute FOREIGN KEY (attribute_id)
REFERENCES attribute(id),
CONSTRAINT pk_ProjectAttribute PRIMARY KEY (project_id, attribute_id)
);
INSERT INTO project (name) VALUES ('project 1 with hardware and software');
INSERT INTO project (name) VALUES ('project 2 with hardware only');
INSERT INTO project (name) VALUES ('project 3 with software only');
INSERT INTO attributeType (name) VALUES ('Hardware');
INSERT INTO attributeType (name) VALUES ('Software');
INSERT INTO attribute (title, type_id) VALUES ('Some hardware 1', 1);
INSERT INTO attribute (title, type_id) VALUES ('Some hardware 2', 1);
INSERT INTO attribute (title, type_id) VALUES ('Some software 1', 2);
INSERT INTO attribute (title, type_id) VALUES ('Some software 2', 2);
INSERT INTO attribute (title, type_id) VALUES ('Some hardware 3', 1);
INSERT INTO ProjectAttribute VALUES (1, 1);
INSERT INTO ProjectAttribute VALUES (1, 2);
INSERT INTO ProjectAttribute VALUES (1, 3);
INSERT INTO ProjectAttribute VALUES (1, 4);
INSERT INTO ProjectAttribute VALUES (2, 1);
INSERT INTO ProjectAttribute VALUES (2, 5);
INSERT INTO ProjectAttribute VALUES (3, 3);
查询1 :
SELECT * FROM project p
INNER JOIN ProjectAttribute pa
ON p.id = pa.project_id
INNER JOIN attribute a
ON a.id = pa.attribute_id
INNER JOIN attributeType t
ON t.id = a.type_id
Results :
| id | name | project_id | attribute_id | id | title | type_id | id | name |
|----|--------------------------------------|------------|--------------|----|-----------------|---------|----|----------|
| 1 | project 1 with hardware and software | 1 | 1 | 1 | Some hardware 1 | 1 | 1 | Hardware |
| 1 | project 1 with hardware and software | 1 | 2 | 2 | Some hardware 2 | 1 | 1 | Hardware |
| 1 | project 1 with hardware and software | 1 | 3 | 3 | Some software 1 | 2 | 2 | Software |
| 1 | project 1 with hardware and software | 1 | 4 | 4 | Some software 2 | 2 | 2 | Software |
| 2 | project 2 with hardware only | 2 | 1 | 1 | Some hardware 1 | 1 | 1 | Hardware |
| 2 | project 2 with hardware only | 2 | 5 | 5 | Some hardware 3 | 1 | 1 | Hardware |
| 3 | project 3 with software only | 3 | 3 | 3 | Some software 1 | 2 | 2 | Software |
答案 1 :(得分:0)
这是我的一个表建议(Type是一个像{Hardware,Software,...}这样的枚举-这意味着MS SQL中ID为Type的Types表):
类型:Id,类型 属性:ID,标题,TypeId Project_Attributes:Project_Id,AttributeId(用于多对多的桥表) 项目:ID,标题,...
实际上一幅价值一千个单词的图片,即使这段代码是在很短的时间内编写的(因此经过一番思考后也需要修改)会给出更多的想法。这是代码优先模型,因此您可以运行并让其为您创建表:
string defaultConString =
@"server=.\SQLExpress;Database=SampleDb;Trusted_Connection=yes;";
void Main()
{
CreateData();
// check db state
ListData();
// Done with sample database. Delete.
// new SampleContext(defaultConString).Database.Delete();
}
private void CreateData()
{
var db = new SampleContext(defaultConString);
if (db.Database.CreateIfNotExists())
{
// Create some types
var tHW = new Type { Name = "Hardware" };
var tSW = new Type { Name = "Software" };
var tFW = new Type { Name = "Firmware" };
db.Types.AddRange(new Type[] {tHW,tSW,tFW});
db.SaveChanges();
// create some Attributes using types above
var a1 = new Attribute
{
Name = "Macbook Pro",
Type = tHW,
AttrProperties = new List<AttrProperty> {
new AttrProperty{ Description=@"15"" retina" },
new AttrProperty{ Description=@"i9-8950HK" },
new AttrProperty{ Description=@"32Gb DDR4 RAM" },
new AttrProperty{ Description=@"512Gb SSD" },
new AttrProperty{ Description=@"AMD Radeon Pro 555" },
new AttrProperty{ Description=@"OSX Mojave 10.14" },
}
};
var a2 = new Attribute
{
Name = "iMac",
Type = tHW,
AttrProperties = new List<AttrProperty> {
new AttrProperty{ Description=@"27"" retina 5K" },
new AttrProperty{ Description=@"i5 3.4Ghz" },
new AttrProperty{ Description=@"40Gb DDR4 RAM" },
new AttrProperty{ Description=@"1Tb Fusion" },
new AttrProperty{ Description=@"AMD Radeon Pro 570" },
new AttrProperty{ Description=@"OSX Mojave 10.14" },
}
};
var a3 = new Attribute
{
Name = "PC",
Type = tHW,
AttrProperties = new List<AttrProperty> {
new AttrProperty{ Description=@"AMD Ryzen Threadripper 1950x" },
new AttrProperty{ Description=@"64Gb RAM" },
new AttrProperty{ Description=@"1 Tb 7400 RPM" },
new AttrProperty{ Description=@"512Gb M2 mSATA" },
new AttrProperty{ Description=@"AMD Radeon Pro 570" },
new AttrProperty{ Description=@"Linux-Debian 9.5" },
}
};
var a4 = new Attribute
{
Name = "Database",
Type = tSW,
AttrProperties = new List<AttrProperty> {
new AttrProperty{ Description=@"postgreSQL" },
new AttrProperty{ Description=@"11 (beta)" },
}
};
var a5 = new Attribute
{
Name = "SomeROM",
Type = tFW,
AttrProperties = new List<AttrProperty> {
new AttrProperty{ Description=@"SomeROM update" },
new AttrProperty{ Description=@"Some version" },
}
};
db.Attributes.AddRange(new Attribute[] {a1,a2,a3,a4,a5});
// Some projects using those
var p1 = new Project
{
Name = "P1",
StartDate = new DateTime(2018, 1, 1),
Attributes = new List<Attribute>() { a1, a2, a4 }
};
var p2 = new Project
{
Name = "P2",
StartDate = new DateTime(2018, 1, 1),
Attributes = new List<Attribute>() { a1, a3, a5 }
};
var p3 = new Project
{
Name = "P3",
StartDate = new DateTime(2018, 1, 1),
Attributes = new List<Attribute>() { a2, a3, a4, a5 }
};
db.Projects.AddRange(new Project[] { p1,p2,p3 });
db.SaveChanges();
}
}
private void ListData()
{
var db = new SampleContext(defaultConString);
// db.Database.Log =Console.Write;
foreach (var p in db.Projects.Include("Attributes").ToList())
{
Console.WriteLine($"Project {p.Name}, started on {p.StartDate}. Has Attributes:");
foreach (var a in p.Attributes)
{
Console.WriteLine($"\t{a.Name} [{a.Type.Name}] ({string.Join(",",a.AttrProperties.Select(ap => ap.Description))})");
}
}
}
public class Type
{
public int TypeId { get; set; }
public string Name { get; set; }
public virtual List<Attribute> Attributes { get; set; }
public Type()
{
Attributes = new List<Attribute>();
}
}
public class Attribute
{
public int AttributeId { get; set; }
public string Name { get; set; }
public int TypeId { get; set; }
public virtual Type Type { get; set; }
public virtual List<Project> Projects { get; set; }
public virtual List<AttrProperty> AttrProperties { get; set; }
public Attribute()
{
Projects = new List<Project>();
}
}
public class AttrProperty
{
public int AttrPropertyId { get; set; }
public string Description { get; set; }
public virtual Attribute Attribute {get;set;}
}
public class Project
{
public int ProjectId { get; set; }
public string Name { get; set; }
public DateTime StartDate { get; set; }
public virtual List<Attribute> Attributes {get;set;}
public Project()
{
Attributes = new List<Attribute>();
}
}
public class SampleContext : DbContext
{
public SampleContext(string connectionString) : base(connectionString) { }
public DbSet<Type> Types { get; set; }
public DbSet<Attribute> Attributes { get; set; }
public DbSet<Project> Projects { get; set; }
}
如果这不是一个多用户的大项目,请查看LiteDB。那可能正是您要寻找的东西,即使不是几分钟,也可以在数小时内学会。